Skip to content

Commit a6a641b

Browse files
2058_fix_inapp_config_parsing_for_2.2.1
1 parent ca7397e commit a6a641b

File tree

4 files changed

+105
-21
lines changed

4 files changed

+105
-21
lines changed

sdk/src/main/java/cloud/mindbox/mobile_sdk/inapp/data/InAppRepositoryImpl.kt

Lines changed: 72 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import cloud.mindbox.mobile_sdk.Mindbox
55
import cloud.mindbox.mobile_sdk.MindboxConfiguration
66
import cloud.mindbox.mobile_sdk.inapp.domain.InAppRepository
77
import cloud.mindbox.mobile_sdk.inapp.mapper.InAppMessageMapper
8+
import cloud.mindbox.mobile_sdk.inapp.presentation.InAppMessageManager
89
import cloud.mindbox.mobile_sdk.logger.MindboxLogger
910
import cloud.mindbox.mobile_sdk.logger.MindboxLoggerImpl
1011
import cloud.mindbox.mobile_sdk.managers.GatewayManager
@@ -13,13 +14,16 @@ import cloud.mindbox.mobile_sdk.models.InAppConfig
1314
import cloud.mindbox.mobile_sdk.models.InAppEventType
1415
import cloud.mindbox.mobile_sdk.models.SegmentationCheckInApp
1516
import cloud.mindbox.mobile_sdk.models.operation.request.InAppHandleRequest
17+
import cloud.mindbox.mobile_sdk.models.operation.response.FormDto
1618
import cloud.mindbox.mobile_sdk.models.operation.response.InAppConfigResponse
19+
import cloud.mindbox.mobile_sdk.models.operation.response.InAppConfigResponseBlank
1720
import cloud.mindbox.mobile_sdk.models.operation.response.PayloadDto
1821
import cloud.mindbox.mobile_sdk.repository.MindboxPreferences
1922
import cloud.mindbox.mobile_sdk.utils.LoggingExceptionHandler
2023
import cloud.mindbox.mobile_sdk.utils.RuntimeTypeAdapterFactory
2124
import com.google.gson.Gson
2225
import com.google.gson.GsonBuilder
26+
import com.google.gson.JsonObject
2327
import com.google.gson.reflect.TypeToken
2428
import kotlinx.coroutines.flow.Flow
2529
import kotlinx.coroutines.flow.map
@@ -84,20 +88,76 @@ internal class InAppRepositoryImpl : InAppRepository {
8488
}
8589

8690
override fun listenInAppConfig(): Flow<InAppConfig?> {
87-
return MindboxPreferences.inAppConfigFlow.map { inAppConfigDto ->
88-
val config = inAppMapper.mapInAppConfigResponseToInAppConfig(
89-
GsonBuilder().registerTypeAdapterFactory(RuntimeTypeAdapterFactory.of(
90-
PayloadDto::class.java,
91-
TYPE_JSON_NAME)
92-
.registerSubtype(PayloadDto.SimpleImage::class.java,
93-
SIMPLE_IMAGE_JSON_NAME))
94-
.create()
95-
.fromJson(inAppConfigDto,
96-
InAppConfigResponse::class.java)
91+
return MindboxPreferences.inAppConfigFlow.map { inAppConfigString ->
92+
MindboxLoggerImpl.d(
93+
parent = this@InAppRepositoryImpl,
94+
message = "CachedConfig : $inAppConfigString"
9795
)
98-
MindboxLoggerImpl.d(this, "Providing config: $config")
99-
config
96+
val configBlank = deserializeToConfigDtoBlank(inAppConfigString)
97+
val filteredInApps = configBlank?.inApps
98+
?.filter { validateInAppVersion(it) }
99+
?.map { inAppDtoBlank ->
100+
inAppMapper.mapToInAppDto(
101+
inAppDtoBlank = inAppDtoBlank,
102+
formDto = deserializeToInAppFormDto(inAppDtoBlank.form),
103+
)
104+
}
105+
val filteredConfig = InAppConfigResponse(
106+
inApps = filteredInApps
107+
)
108+
return@map inAppMapper.mapInAppConfigResponseToInAppConfig(filteredConfig).also { inAppConfig ->
109+
MindboxLoggerImpl.d(
110+
parent = this@InAppRepositoryImpl,
111+
message = "Providing config: $inAppConfig"
112+
)
113+
}
114+
}
115+
}
116+
117+
private fun deserializeToConfigDtoBlank(inAppConfig: String): InAppConfigResponseBlank? {
118+
val result = runCatching {
119+
gson.fromJson(inAppConfig, InAppConfigResponseBlank::class.java)
100120
}
121+
result.exceptionOrNull()?.let { error ->
122+
MindboxLoggerImpl.e(
123+
parent = this@InAppRepositoryImpl,
124+
message = "Failed to parse inAppConfig: $inAppConfig",
125+
exception = error
126+
)
127+
}
128+
return result.getOrNull()
129+
}
130+
131+
private fun deserializeToInAppFormDto(inAppForm: JsonObject?): FormDto? {
132+
val result = runCatching {
133+
GsonBuilder().registerTypeAdapterFactory(RuntimeTypeAdapterFactory.of(
134+
PayloadDto::class.java,
135+
TYPE_JSON_NAME)
136+
.registerSubtype(PayloadDto.SimpleImage::class.java,
137+
SIMPLE_IMAGE_JSON_NAME))
138+
.create()
139+
.fromJson(inAppForm,
140+
FormDto::class.java)
141+
}
142+
result.exceptionOrNull()?.let { error ->
143+
MindboxLoggerImpl.e(
144+
parent = this@InAppRepositoryImpl,
145+
message = "Failed to parse JsonObject: $inAppForm",
146+
exception = error
147+
)
148+
}
149+
return result.getOrNull()
150+
}
151+
152+
private fun validateInAppVersion(inAppDto: InAppConfigResponseBlank.InAppDtoBlank): Boolean {
153+
val sdkVersion = inAppDto.sdkVersion ?: return false
154+
val minVersionValid = sdkVersion.minVersion?.let { min ->
155+
min <= InAppMessageManager.CURRENT_IN_APP_VERSION
156+
} ?: true
157+
val maxVersionValid = sdkVersion.maxVersion?.let { max ->
158+
max >= InAppMessageManager.CURRENT_IN_APP_VERSION
159+
} ?: true
160+
return minVersionValid && maxVersionValid
101161
}
102162

103163
companion object {

sdk/src/main/java/cloud/mindbox/mobile_sdk/inapp/domain/InAppInteractor.kt

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ internal class InAppInteractor {
5959
null
6060
}
6161

62-
when (val type = inApp?.form?.variants?.first()) {
62+
when (val type = inApp?.form?.variants?.firstOrNull()) {
6363
is Payload.SimpleImage -> InAppType.SimpleImage(inAppId = inApp.id,
6464
imageUrl = type.imageUrl,
6565
redirectUrl = type.redirectUrl,
@@ -77,7 +77,6 @@ internal class InAppInteractor {
7777
MindboxLoggerImpl.d(this,
7878
"Already shown innaps: ${inAppRepositoryImpl.getShownInApps()}")
7979
return config.copy(inApps = config.inApps
80-
.filter { inApp -> validateInAppVersion(inApp) }
8180
.filter { inApp -> validateInAppNotShown(inApp) && validateInAppTargeting(inApp) }
8281
)
8382
}
@@ -148,13 +147,6 @@ internal class InAppInteractor {
148147
}
149148
}
150149

151-
private fun validateInAppVersion(inApp: InApp): Boolean {
152-
return ((inApp.minVersion?.let { min -> min <= InAppMessageManager.CURRENT_IN_APP_VERSION }
153-
?: true) && (inApp.maxVersion?.let { max -> max >= InAppMessageManager.CURRENT_IN_APP_VERSION }
154-
?: true))
155-
}
156-
157-
158150
suspend fun fetchInAppConfig(context: Context, configuration: MindboxConfiguration) {
159151
inAppRepositoryImpl.fetchInAppConfig(context, configuration)
160152
}

sdk/src/main/java/cloud/mindbox/mobile_sdk/inapp/mapper/InAppMessageMapper.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,27 @@ import cloud.mindbox.mobile_sdk.models.*
44
import cloud.mindbox.mobile_sdk.models.operation.request.IdsRequest
55
import cloud.mindbox.mobile_sdk.models.operation.request.SegmentationCheckRequest
66
import cloud.mindbox.mobile_sdk.models.operation.request.SegmentationDataRequest
7+
import cloud.mindbox.mobile_sdk.models.operation.response.*
78
import cloud.mindbox.mobile_sdk.models.operation.response.InAppConfigResponse
9+
import cloud.mindbox.mobile_sdk.models.operation.response.InAppConfigResponseBlank
810
import cloud.mindbox.mobile_sdk.models.operation.response.PayloadDto
911
import cloud.mindbox.mobile_sdk.models.operation.response.SegmentationCheckResponse
1012
import cloud.mindbox.mobile_sdk.models.operation.response.TargetingDto
1113

1214
internal class InAppMessageMapper {
15+
fun mapToInAppDto (
16+
inAppDtoBlank: InAppConfigResponseBlank.InAppDtoBlank,
17+
formDto: FormDto?,
18+
): InAppDto {
19+
return inAppDtoBlank.let { inApp ->
20+
InAppDto(
21+
id = inApp.id,
22+
sdkVersion = inApp.sdkVersion,
23+
targeting = inApp.targeting,
24+
form = formDto
25+
)
26+
}
27+
}
1328

1429
fun mapInAppConfigResponseToInAppConfig(inAppConfigResponse: InAppConfigResponse?): InAppConfig? {
1530
return inAppConfigResponse?.let { inAppConfigDto ->

sdk/src/main/java/cloud/mindbox/mobile_sdk/models/operation/response/InAppConfigResponse.kt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cloud.mindbox.mobile_sdk.models.operation.response
22

33

4+
import com.google.gson.JsonObject
45
import com.google.gson.annotations.SerializedName
56

67
internal data class InAppConfigResponse(
@@ -52,3 +53,19 @@ internal sealed class PayloadDto {
5253
val intentPayload: String?,
5354
) : PayloadDto()
5455
}
56+
57+
internal data class InAppConfigResponseBlank(
58+
@SerializedName("inapps")
59+
val inApps: List<InAppDtoBlank>?,
60+
) {
61+
internal data class InAppDtoBlank(
62+
@SerializedName("id")
63+
val id: String,
64+
@SerializedName("sdkVersion")
65+
val sdkVersion: SdkVersion?,
66+
@SerializedName("targeting")
67+
val targeting: TargetingDto?,
68+
@SerializedName("form")
69+
val form: JsonObject?, // FormDto. Parsed after filtering inApp versions.
70+
)
71+
}

0 commit comments

Comments
 (0)