1 min read

Custom Data v2

Custom data is a mechanism that allows your app to send or receive extra information in the existing PoqSDK models to accommodate your customisations. Custom data v2 defines 3 models:

  • NetworkCustomData: model to receive data which is a typealias of Map<String, Any>.
  • NetworkCustomDataRequest: model to send data which is a typealias of Any.
  • CustomData: empty interface that all domain custom models extends.

Each network and domain models define their own custom data model using one of those 3 models. This allows to create specific mapper interfaces for each custom data, constructing the names as {Layer}to{Layer}{ModelNameCustomData}Mapper.

interface FeatureCustomData : CustomData
typealias NetworkStoreCustomData = NetworkCustomData
interface NetworkToDomainFeatureCustomDataMapper {
fun map(networkFeatureCustomData: NetworkFeatureCustomData?): FeatureCustomData?
}

Receive custom data

To add custom data to domain models you need to:

  1. Define a new domain model CustomModel which represents your extra fields extending the appropriate custom data model.
  2. Define a new network model NetworkCustomModel which represents your extra fields matching the backend response, using @Keep or @JsonClass(generateAdapter = true) depending if you use Gson or Moshi.
  3. Create a new implementation of the appropriate interface mapper using the method mapCustomData.
    @JsonClass(generateAdapter = true)
    data class NetworkMyCustomData(val customValue: String?)
    data class MyCustomData(val value: String) : FeatureCustomData
    class NetworkToDomainMyCustomDataMapper : NetworkToDomainFeatureCustomDataMapper {
    override fun map(networkFeatureCustomData: NetworkFeatureCustomData?): FeatureCustomData? {
    return mapCustomModels(mapCustomData<NetworkMyCustomData>(networkFeatureCustomData))
    }
    private fun mapCustomModels(networkMyCustomData: NetworkMyCustomData?): MyCustomData? {
    return networkMyCustomData?.customValue?.let { MyCustomData(it) }
    }
    }
  4. Provide your new mapper implementation via Koin.
  5. Where you want to use that extra information: (poqModel.customData as CustomModel).newField

In some features there is also a UI model, in these cases the Android PoqSDK will map your custom data automatically to the UI model.

If you need to use your custom data fields in your custom layouts via DataBinding, PoqSDK ViewModels expose the custom data or the whole object containing the custom data as LiveData, so you can:

  1. Create an extension function over the ViewModel interface
    fun PoqViewModel.customField(): LiveData<{YourFieldType}> {
    return Transformations.map(customData){ it.newField }
    }
  2. Use your new LiveData in your layout:
    <data>
    <variable
    name="viewModel"
    type="{package}.PoqViewModel" />
    <import type="{package}.FileExtensionsKt" />
    </data>
    <View
    android:field="@{FileExtensionsKt.customField(viewModel)}" />

Send custom data

When you need to send custom data to your backend, you need to:

  1. Define a new domain model CustomModel which represents your extra fields extending the appropriate custom data model.
  2. Add your custom data to the Domain model object. This is different for each domain and specific scenario.
  3. Define a new network model NetworkCustomModel which represents your extra fields matching the backend response, using @Keep or @JsonClass(generateAdapter = true) depending if you use Gson or Moshi.
  4. Create a new implementation of the appropriate mapper interface mapping your domain model to your network model.
    @JsonClass(generateAdapter = true)
    data class NetworkMyCustomData(val customValue: String)
    data class MyCustomData(val value: String) : FeatureCustomData
    class DomainToNetworkMyCustomDataMapper : DomainToNetworkFeatureCustomDataMapper {
    override fun map(featureCustomData: FeatureCustomData?): NetworkFeatureCustomData? {
    return if(featureCustomData != null){
    NetworkFeatureCustomData(featureCustomData.value)
    } else {
    null
    }
    }
    }
  5. Provide your new mapper implementation via Koin.