diff --git a/build.gradle b/build.gradle
index f8f5143a..18d5d471 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,7 +6,7 @@ import io.gitlab.arturbosch.detekt.DetektCreateBaselineTask
buildscript {
ext {
release = [
- versionName: "7.4.1",
+ versionName: "7.5.0",
versionCode: 1
]
}
diff --git a/config/detekt/baseline.xml b/config/detekt/baseline.xml
index a91d68c2..65ec9b6a 100644
--- a/config/detekt/baseline.xml
+++ b/config/detekt/baseline.xml
@@ -270,6 +270,7 @@
TooManyFunctions:QProductCenterManager.kt$QProductCenterManager : PurchasesListenerUserStateProvider
TooManyFunctions:QRemoteConfigManager.kt$QRemoteConfigManager
TooManyFunctions:QRepository.kt$QRepository
+ TooManyFunctions:QUserPropertiesManager.kt$QUserPropertiesManager : FacebookAttributionListener
TooManyFunctions:Qonversion.kt$Qonversion
TooManyFunctions:QonversionBillingService.kt$QonversionBillingService : PurchasesUpdatedListenerConnectionListenerBillingService
TooManyFunctions:QonversionInternal.kt$QonversionInternal : QonversionLifecycleDelegateAppStateProvider
diff --git a/fastlane/report.xml b/fastlane/report.xml
index 62c5fd4e..da5ada95 100644
--- a/fastlane/report.xml
+++ b/fastlane/report.xml
@@ -5,7 +5,7 @@
-
+
diff --git a/sdk/src/main/java/com/qonversion/android/sdk/internal/QRemoteConfigManager.kt b/sdk/src/main/java/com/qonversion/android/sdk/internal/QRemoteConfigManager.kt
index 4d537b65..df770515 100644
--- a/sdk/src/main/java/com/qonversion/android/sdk/internal/QRemoteConfigManager.kt
+++ b/sdk/src/main/java/com/qonversion/android/sdk/internal/QRemoteConfigManager.kt
@@ -5,6 +5,7 @@ import com.qonversion.android.sdk.dto.QRemoteConfigList
import com.qonversion.android.sdk.dto.QonversionError
import com.qonversion.android.sdk.internal.provider.UserStateProvider
import com.qonversion.android.sdk.internal.services.QRemoteConfigService
+import com.qonversion.android.sdk.listeners.QonversionEmptyCallback
import com.qonversion.android.sdk.listeners.QonversionExperimentAttachCallback
import com.qonversion.android.sdk.listeners.QonversionRemoteConfigCallback
import com.qonversion.android.sdk.listeners.QonversionRemoteConfigListCallback
@@ -31,6 +32,7 @@ internal class QRemoteConfigManager @Inject constructor(
lateinit var userStateProvider: UserStateProvider
private var loadingStates = mutableMapOf()
private val listRequests = mutableListOf()
+ lateinit var userPropertiesManager: QUserPropertiesManager
fun handlePendingRequests() {
loadingStates.filter { it.value.callbacks.isNotEmpty() }
@@ -77,14 +79,19 @@ internal class QRemoteConfigManager @Inject constructor(
loadingState.isInProgress = true
loadingState.loadedConfig = null
- remoteConfigService.loadRemoteConfig(contextKey, object : QonversionRemoteConfigCallback {
- override fun onSuccess(remoteConfig: QRemoteConfig) {
- loadingState.loadedConfig = remoteConfig
- fireToCallbacks(contextKey) { onSuccess(remoteConfig) }
- }
- override fun onError(error: QonversionError) {
- fireToCallbacks(contextKey) { onError(error) }
+ userPropertiesManager.forceSendProperties(object : QonversionEmptyCallback {
+ override fun onComplete() {
+ remoteConfigService.loadRemoteConfig(contextKey, object : QonversionRemoteConfigCallback {
+ override fun onSuccess(remoteConfig: QRemoteConfig) {
+ loadingState.loadedConfig = remoteConfig
+ fireToCallbacks(contextKey) { onSuccess(remoteConfig) }
+ }
+
+ override fun onError(error: QonversionError) {
+ fireToCallbacks(contextKey) { onError(error) }
+ }
+ })
}
})
}
@@ -106,11 +113,15 @@ internal class QRemoteConfigManager @Inject constructor(
return
}
- remoteConfigService.loadRemoteConfigs(
- contextKeys,
- includeEmptyContextKey,
- getRemoteConfigListCallbackWrapper(callback),
- )
+ userPropertiesManager.forceSendProperties(object : QonversionEmptyCallback {
+ override fun onComplete() {
+ remoteConfigService.loadRemoteConfigs(
+ contextKeys,
+ includeEmptyContextKey,
+ getRemoteConfigListCallbackWrapper(callback),
+ )
+ }
+ })
}
fun loadRemoteConfigList(callback: QonversionRemoteConfigListCallback) {
@@ -119,7 +130,11 @@ internal class QRemoteConfigManager @Inject constructor(
return
}
- remoteConfigService.loadRemoteConfigs(getRemoteConfigListCallbackWrapper(callback))
+ userPropertiesManager.forceSendProperties(object : QonversionEmptyCallback {
+ override fun onComplete() {
+ remoteConfigService.loadRemoteConfigs(getRemoteConfigListCallbackWrapper(callback))
+ }
+ })
}
fun attachUserToExperiment(experimentId: String, groupId: String, callback: QonversionExperimentAttachCallback) {
diff --git a/sdk/src/main/java/com/qonversion/android/sdk/internal/QUserPropertiesManager.kt b/sdk/src/main/java/com/qonversion/android/sdk/internal/QUserPropertiesManager.kt
index 6148b4d1..e78e98dd 100644
--- a/sdk/src/main/java/com/qonversion/android/sdk/internal/QUserPropertiesManager.kt
+++ b/sdk/src/main/java/com/qonversion/android/sdk/internal/QUserPropertiesManager.kt
@@ -14,6 +14,7 @@ import com.qonversion.android.sdk.internal.logger.Logger
import com.qonversion.android.sdk.internal.provider.AppStateProvider
import com.qonversion.android.sdk.internal.repository.QRepository
import com.qonversion.android.sdk.internal.storage.PropertiesStorage
+import com.qonversion.android.sdk.listeners.QonversionEmptyCallback
import com.qonversion.android.sdk.listeners.QonversionUserPropertiesCallback
import javax.inject.Inject
@@ -31,6 +32,7 @@ internal class QUserPropertiesManager @Inject internal constructor(
private var isSendingScheduled = false
private var retryDelay = PROPERTY_UPLOAD_MIN_DELAY
private var retriesCounter = 0
+ private var completions = mutableListOf()
companion object {
private const val LOOPER_THREAD_NAME = "userPropertiesThread"
@@ -67,19 +69,27 @@ internal class QUserPropertiesManager @Inject internal constructor(
setCustomUserProperty(QUserPropertyKey.FacebookAttribution.userPropertyCode, id)
}
- fun forceSendProperties() {
+ public fun forceSendProperties(callback: QonversionEmptyCallback? = null) {
if (isRequestInProgress) {
+ if (callback != null) {
+ completions.add(callback)
+ }
return
}
val properties = propertiesStorage.getProperties()
if (properties.isNotEmpty()) {
+ if (callback != null) {
+ completions.add(callback)
+ }
+
isRequestInProgress = true
isSendingScheduled = false
repository.sendProperties(properties,
onSuccess = { result ->
+ fireCallbacks()
result.propertyErrors.forEach { propertyError ->
logger.error("Failed to save property ${propertyError.key}: ${propertyError.error}")
}
@@ -92,6 +102,7 @@ internal class QUserPropertiesManager @Inject internal constructor(
propertiesStorage.clear(properties)
},
onError = {
+ fireCallbacks()
isRequestInProgress = false
if (it.code === QonversionErrorCode.InvalidClientUid) {
@@ -108,9 +119,18 @@ internal class QUserPropertiesManager @Inject internal constructor(
retryPropertiesRequest()
}
})
+ } else {
+ callback?.onComplete()
}
}
+ private fun fireCallbacks() {
+ val callbacks = completions.toList()
+ completions.clear()
+
+ callbacks.forEach { callback -> callback.onComplete() }
+ }
+
@VisibleForTesting
fun retryPropertiesRequest() {
retriesCounter++
diff --git a/sdk/src/main/java/com/qonversion/android/sdk/internal/QonversionInternal.kt b/sdk/src/main/java/com/qonversion/android/sdk/internal/QonversionInternal.kt
index 35f0e7e6..dd74687c 100644
--- a/sdk/src/main/java/com/qonversion/android/sdk/internal/QonversionInternal.kt
+++ b/sdk/src/main/java/com/qonversion/android/sdk/internal/QonversionInternal.kt
@@ -104,6 +104,8 @@ internal class QonversionInternal(
userPropertiesManager.productCenterManager = productCenterManager
userPropertiesManager.sendFacebookAttribution()
+ remoteConfigManager.userPropertiesManager = userPropertiesManager
+
val lifecycleHandler = AppLifecycleHandler(this)
postToMainThread { ProcessLifecycleOwner.get().lifecycle.addObserver(lifecycleHandler) }
diff --git a/sdk/src/main/java/com/qonversion/android/sdk/listeners/QonversionCallback.kt b/sdk/src/main/java/com/qonversion/android/sdk/listeners/QonversionCallback.kt
index 48deeeca..6ec342b3 100644
--- a/sdk/src/main/java/com/qonversion/android/sdk/listeners/QonversionCallback.kt
+++ b/sdk/src/main/java/com/qonversion/android/sdk/listeners/QonversionCallback.kt
@@ -70,3 +70,8 @@ interface QonversionUserPropertiesCallback {
fun onSuccess(userProperties: QUserProperties)
fun onError(error: QonversionError)
}
+
+interface QonversionEmptyCallback {
+
+ fun onComplete()
+}