Skip to content

Commit

Permalink
Release 7.3.0
Browse files Browse the repository at this point in the history
Release 7.3.0
  • Loading branch information
SpertsyanKM authored Mar 28, 2024
2 parents 80e5ac1 + 5ac91d2 commit 1633e07
Show file tree
Hide file tree
Showing 15 changed files with 275 additions and 63 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import io.gitlab.arturbosch.detekt.DetektCreateBaselineTask
buildscript {
ext {
release = [
versionName: "7.2.0",
versionName: "7.3.0",
versionCode: 1
]
}
Expand Down
1 change: 1 addition & 0 deletions config/detekt/baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@
<ID>TooManyFunctions:LegacyBillingClientWrapper.kt$LegacyBillingClientWrapper : BillingClientWrapperBaseIBillingClientWrapper</ID>
<ID>TooManyFunctions:QAutomationsManager.kt$QAutomationsManager</ID>
<ID>TooManyFunctions:QProductCenterManager.kt$QProductCenterManager : PurchasesListenerUserStateProvider</ID>
<ID>TooManyFunctions:QRemoteConfigManager.kt$QRemoteConfigManager</ID>
<ID>TooManyFunctions:QRepository.kt$QRepository</ID>
<ID>TooManyFunctions:Qonversion.kt$Qonversion</ID>
<ID>TooManyFunctions:QonversionBillingService.kt$QonversionBillingService : PurchasesUpdatedListenerConnectionListenerBillingService</ID>
Expand Down
2 changes: 1 addition & 1 deletion fastlane/report.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@



<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000564">
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000374">

</testcase>

Expand Down
21 changes: 21 additions & 0 deletions sdk/src/main/java/com/qonversion/android/sdk/Qonversion.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.qonversion.android.sdk.listeners.QonversionEntitlementsCallback
import com.qonversion.android.sdk.listeners.QonversionOfferingsCallback
import com.qonversion.android.sdk.listeners.QonversionProductsCallback
import com.qonversion.android.sdk.listeners.QonversionRemoteConfigCallback
import com.qonversion.android.sdk.listeners.QonversionRemoteConfigListCallback
import com.qonversion.android.sdk.listeners.QonversionRemoteConfigurationAttachCallback
import com.qonversion.android.sdk.listeners.QonversionUserCallback
import com.qonversion.android.sdk.listeners.QonversionUserPropertiesCallback
Expand Down Expand Up @@ -129,6 +130,26 @@ interface Qonversion {
*/
fun remoteConfig(contextKey: String, callback: QonversionRemoteConfigCallback)

/**
* Returns Qonversion remote config objects by a list of [contextKeys].
* Use this function to get the remote configs with specific payload and experiment info.
* @param includeEmptyContextKey - set to true if you want to include remote config
* with empty context key to the result
* @param callback - callback that will be called when response is received
*/
fun remoteConfigList(
contextKeys: List<String>,
includeEmptyContextKey: Boolean,
callback: QonversionRemoteConfigListCallback
)

/**
* Returns Qonversion remote config objects for all existing context key (including empty one).
* Use this function to get the remote configs with specific payload and experiment info.
* @param callback - callback that will be called when response is received
*/
fun remoteConfigList(callback: QonversionRemoteConfigListCallback)

/**
* This function should be used for the test purposes only. Do not forget to delete the usage of this function before the release.
* Use this function to attach the user to the experiment.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ data class QRemoteConfig internal constructor(
@Json(name = "source") internal val sourceApi: QRemoteConfigurationSource?
) {
val source: QRemoteConfigurationSource get() = sourceApi!!

internal val isCorrect = sourceApi != null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.qonversion.android.sdk.dto

data class QRemoteConfigList internal constructor(
internal val remoteConfigs: List<QRemoteConfig>
) {
fun remoteConfigForContextKey(key: String): QRemoteConfig? {
return remoteConfigs.find { it.source.contextKey == key }
}

val remoteConfigForEmptyContextKey: QRemoteConfig? = remoteConfigs.find {
it.source.contextKey == null
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package com.qonversion.android.sdk.internal

import com.qonversion.android.sdk.dto.QRemoteConfig
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.QonversionExperimentAttachCallback
import com.qonversion.android.sdk.listeners.QonversionRemoteConfigCallback
import com.qonversion.android.sdk.listeners.QonversionRemoteConfigListCallback
import com.qonversion.android.sdk.listeners.QonversionRemoteConfigurationAttachCallback
import javax.inject.Inject

private val EmptyContextKey: String? = null

internal class QRemoteConfigManager @Inject constructor(
private val remoteConfigService: QRemoteConfigService,
private val internalConfig: InternalConfig
) {
internal class LoadingState(
var loadedConfig: QRemoteConfig? = null,
Expand Down Expand Up @@ -59,7 +62,7 @@ internal class QRemoteConfigManager @Inject constructor(

loadingState.isInProgress = true
loadingState.loadedConfig = null
remoteConfigService.loadRemoteConfig(internalConfig.uid, contextKey, object : QonversionRemoteConfigCallback {
remoteConfigService.loadRemoteConfig(contextKey, object : QonversionRemoteConfigCallback {
override fun onSuccess(remoteConfig: QRemoteConfig) {
loadingState.loadedConfig = remoteConfig
fireToCallbacks(contextKey) { onSuccess(remoteConfig) }
Expand All @@ -71,30 +74,77 @@ internal class QRemoteConfigManager @Inject constructor(
})
}

fun loadRemoteConfigList(
contextKeys: List<String>,
includeEmptyContextKey: Boolean,
callback: QonversionRemoteConfigListCallback
) {
val allKeys = if (includeEmptyContextKey) contextKeys + EmptyContextKey else contextKeys
if (allKeys.all { loadingStates[it]?.loadedConfig != null }) {
val configs = allKeys.mapNotNull { loadingStates[it]?.loadedConfig }
callback.onSuccess(QRemoteConfigList(configs))
return
}

remoteConfigService.loadRemoteConfigs(
contextKeys,
includeEmptyContextKey,
getRemoteConfigListCallbackWrapper(callback),
)
}

fun loadRemoteConfigList(callback: QonversionRemoteConfigListCallback) {
remoteConfigService.loadRemoteConfigs(getRemoteConfigListCallbackWrapper(callback))
}

fun attachUserToExperiment(experimentId: String, groupId: String, callback: QonversionExperimentAttachCallback) {
loadingStates[null]?.loadedConfig = null
remoteConfigService.attachUserToExperiment(experimentId, groupId, internalConfig.uid, callback)
loadingStates[EmptyContextKey]?.loadedConfig = null
remoteConfigService.attachUserToExperiment(experimentId, groupId, callback)
}

fun detachUserFromExperiment(experimentId: String, callback: QonversionExperimentAttachCallback) {
loadingStates[null]?.loadedConfig = null
remoteConfigService.detachUserFromExperiment(experimentId, internalConfig.uid, callback)
loadingStates[EmptyContextKey]?.loadedConfig = null
remoteConfigService.detachUserFromExperiment(experimentId, callback)
}

fun attachUserToRemoteConfiguration(
remoteConfigurationId: String,
callback: QonversionRemoteConfigurationAttachCallback
) {
loadingStates[null]?.loadedConfig = null
remoteConfigService.attachUserToRemoteConfiguration(remoteConfigurationId, internalConfig.uid, callback)
loadingStates[EmptyContextKey]?.loadedConfig = null
remoteConfigService.attachUserToRemoteConfiguration(remoteConfigurationId, callback)
}

fun detachUserFromRemoteConfiguration(
remoteConfigurationId: String,
callback: QonversionRemoteConfigurationAttachCallback
) {
loadingStates[null]?.loadedConfig = null
remoteConfigService.detachUserFromRemoteConfiguration(remoteConfigurationId, internalConfig.uid, callback)
loadingStates[EmptyContextKey]?.loadedConfig = null
remoteConfigService.detachUserFromRemoteConfiguration(remoteConfigurationId, callback)
}

private fun getRemoteConfigListCallbackWrapper(
callback: QonversionRemoteConfigListCallback
): QonversionRemoteConfigListCallback {
// Remembering loading states for the case of user change -
// if it happens, we won't store remote configs for different user.
val localLoadingStates = loadingStates
return object : QonversionRemoteConfigListCallback {
override fun onSuccess(remoteConfigList: QRemoteConfigList) {
remoteConfigList.remoteConfigs.forEach { remoteConfig ->
val contextKey = remoteConfig.source.contextKey
val loadingState = localLoadingStates[contextKey] ?: LoadingState()
loadingState.loadedConfig = remoteConfig
localLoadingStates[contextKey] = loadingState
}

callback.onSuccess(remoteConfigList)
}

override fun onError(error: QonversionError) {
callback.onError(error)
}
}
}

private fun fireToCallbacks(contextKey: String?, action: QonversionRemoteConfigCallback.() -> Unit) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import com.qonversion.android.sdk.dto.QPurchaseModel
import com.qonversion.android.sdk.dto.QPurchaseUpdateModel
import com.qonversion.android.sdk.dto.entitlements.QEntitlement
import com.qonversion.android.sdk.dto.QRemoteConfig
import com.qonversion.android.sdk.dto.QRemoteConfigList
import com.qonversion.android.sdk.dto.properties.QUserPropertyKey
import com.qonversion.android.sdk.dto.QonversionError
import com.qonversion.android.sdk.dto.eligibility.QEligibility
Expand All @@ -33,6 +34,7 @@ import com.qonversion.android.sdk.listeners.QonversionRemoteConfigCallback
import com.qonversion.android.sdk.listeners.QonversionEligibilityCallback
import com.qonversion.android.sdk.listeners.QonversionUserCallback
import com.qonversion.android.sdk.listeners.QEntitlementsUpdateListener
import com.qonversion.android.sdk.listeners.QonversionRemoteConfigListCallback
import com.qonversion.android.sdk.listeners.QonversionRemoteConfigurationAttachCallback
import com.qonversion.android.sdk.listeners.QonversionUserPropertiesCallback

Expand Down Expand Up @@ -213,6 +215,37 @@ internal class QonversionInternal(
}) ?: logLaunchErrorForFunctionName(object {}.javaClass.enclosingMethod?.name)
}

override fun remoteConfigList(
contextKeys: List<String>,
includeEmptyContextKey: Boolean,
callback: QonversionRemoteConfigListCallback
) {
remoteConfigManager?.loadRemoteConfigList(
contextKeys,
includeEmptyContextKey,
object : QonversionRemoteConfigListCallback {
override fun onSuccess(remoteConfigList: QRemoteConfigList) {
postToMainThread { callback.onSuccess(remoteConfigList) }
}

override fun onError(error: QonversionError) {
postToMainThread { callback.onError(error) }
}
}) ?: logLaunchErrorForFunctionName(object {}.javaClass.enclosingMethod?.name)
}

override fun remoteConfigList(callback: QonversionRemoteConfigListCallback) {
remoteConfigManager?.loadRemoteConfigList(object : QonversionRemoteConfigListCallback {
override fun onSuccess(remoteConfigList: QRemoteConfigList) {
postToMainThread { callback.onSuccess(remoteConfigList) }
}

override fun onError(error: QonversionError) {
postToMainThread { callback.onError(error) }
}
}) ?: logLaunchErrorForFunctionName(object {}.javaClass.enclosingMethod?.name)
}

override fun attachUserToExperiment(
experimentId: String,
groupId: String,
Expand Down
17 changes: 16 additions & 1 deletion sdk/src/main/java/com/qonversion/android/sdk/internal/api/Api.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import retrofit2.http.DELETE
import retrofit2.http.Path
import retrofit2.http.QueryMap
import retrofit2.http.Headers
import retrofit2.http.Query
import retrofit2.http.Url

internal interface Api {
Expand Down Expand Up @@ -74,9 +75,23 @@ internal interface Api {

@GET("v3/remote-config")
fun remoteConfig(
@QueryMap params: Map<String, String>
@Query("user_id") userId: String,
@Query("context_key") contextKey: String?
): Call<QRemoteConfig>

@GET("v3/remote-configs")
fun remoteConfigList(
@Query("user_id") userId: String,
@Query("all_context_keys") allContextKeys: Boolean = true,
): Call<List<QRemoteConfig>>

@GET("v3/remote-configs")
fun remoteConfigList(
@Query("user_id") userId: String,
@Query("context_key") contextKeys: List<String>,
@Query("with_empty_context_key") includeEmptyContextKey: Boolean,
): Call<List<QRemoteConfig>>

@POST("v3/experiments/{id}/users/{user_id}")
fun attachUserToExperiment(
@Path("id") experimentId: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.qonversion.android.sdk.internal.api
internal enum class RequestType {
Init,
RemoteConfig,
RemoteConfigList,
AttachUserToExperiment,
DetachUserFromExperiment,
Purchase,
Expand Down
Loading

0 comments on commit 1633e07

Please sign in to comment.