Android 4.+ migration guide
Upgrading version
Increase the dependency version in your app build.gradle file to upgrade your Qonversion SDK to the latest version
dependencies {
implementation 'io.qonversion.android.sdk:sdk:4.+'
}
Initialization
Qonversion Android SDK 4 contains significant changes in how the library is initialized. We are moving from a singletons approach to the instance-based one. Before, you initialized Qonversion using the launch
call:
public class App : Application {
override fun onCreate() {
super.onCreate()
Qonversion.launch(this, "projectKey", false)
}
}
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
Qonversion.launch(this, "projectKey", false);
}
}
Now, instead, you should create a QonversionConfig
object using nested Builder
and provide it to initialization method as follows:
public class App : Application {
override fun onCreate() {
super.onCreate()
val qonversionConfig = QonversionConfig.Builder(
this,
"projectKey",
QLaunchMode.SubscriptionManagement
).build()
Qonversion.initialize(qonversionConfig)
}
}
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
final QonversionConfig qonversionConfig = new QonversionConfig.Builder(
this,
"projectKey",
QLaunchMode.Infrastructure
).build();
Qonversion.initialize(qonversionConfig);
}
}
Note that instead of providing the observeMode
flag to the launch
call, you should provide a concrete value from the QLaunchMode
enum, depending on which mode you use Qonversion. Also, we've renamed our modes to make them more transparent for users:
- "Observe" mode becomes "Analytics" mode,
- "Infrastructure" mode becomes "Subscription Management" mode.
After the initialization, you can access the Qonversion instance whenever you want as follows:
Qonversion.shared
Qonversion.getSharedInstance();
So you should replace all your Qonversion calls with the construction above.
Also, if you were using Qonversion.setDebugMode()
for testing purposes, you should now call the setEnvironment(QEnvironment.Sandbox)
method of the QonversionConfig.Builder
.
As no launch
method is available anymore, you won't get QLaunchResult
as a result. The good news is that there are analogues for all the fields you might have been using from there:
- for
uid
, calluserInfo()
and get theQUser.qonversionId
from the result, - for
products
callproducts()
, - for
offerings
callofferings()
, - for
permissions
callcheckEntitlements()
, experiments
field has no analogue, as theexperiments
method was removed for now.
Entitlements
We are on the way to renaming permissions to entitlements as this naming suits more what it is used for. So, the following objects and methods were renamed in this release:
Version <4 | Version 4+ |
---|---|
QPermission | QEntitlement |
QonversionPermissionsCallback | QonversionEntitlementsCallback |
QProductRenewState | QEntitlementRenewState |
QPermissionSource | QEntitlementSource |
QPermissionsCacheLifetime | QEntitlementsCacheLifetime |
checkPermissions | checkEntitlements |
UpdatedPurchasesListener | QEntitlementsUpdateListener |
The QEntitlement
class contains the same information as the QPermission
with small renamings.
permissionsID
was renamed toid
,productID
was renamed toproductId
,isActive
became a Kotlin property, so it should now be accessed as a property.
There is no setUpdatedPurchasesListener
method in Qonversion. You should provide UpdatedEntitlementsListener
to QonversionConfig.Builder
during the initialization using the setUpdatedEntitlementsListener
method.
The same change is made to the setPermissionsCacheLifetime
method. Now you can set the required lifetime using QonversionConfig.Builder.setEntitlementsCacheLifetime
while Qonversion initialization.
val qonversionConfig = QonversionConfig.Builder(
this,
"projectKey",
QLaunchMode.SubscriptionManagement
)
.setEntitlementsUpdateListener(object : EntitlementsUpdateListener {
override fun onEntitlementsUpdated(entitlements: Map<String, QEntitlement>) {
// handle updated entitlements
}
})
.setEntitlementsCacheLifetime(QEntitlementsCacheLifetime.Year)
.build()
Qonversion.initialize(qonversionConfig)
final QonversionConfig qonversionConfig = new QonversionConfig.Builder(
this,
"projectKey",
QLaunchMode.Infrastructure
)
.setEntitlementsCacheLifetime(QEntitlementsCacheLifetime.Year)
.setEntitlementsUpdateListener(entitlements -> {/* handle updated entitlements */})
.build();
Qonversion.initialize(qonversionConfig);
Automation changes
We've also changed the way the Automations
is used. As in Qonversion, you should use Automations
via the shared instance. On the first access, it will be initialized and returned. Then the initialized instance will be used.
You should access the shared instance of
Automations
strictly after you initialize Qonversion, else an exception will be thrown.
public class App : Application {
override fun onCreate() {
super.onCreate()
val qonversionConfig = QonversionConfig.Builder(
this,
"projectKey",
QLaunchMode.SubscriptionManagement
).build()
Qonversion.initialize(qonversionConfig)
Automations.shared.setDelegate(...)
}
}
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
final QonversionConfig qonversionConfig = new QonversionConfig.Builder(
this,
"projectKey",
QLaunchMode.Infrastructure
).build();
Qonversion.initialize(qonversionConfig);
Automations.getSharedInstance().setDelegate(...);
}
}
Also, the methods for working with push notifications were moved from Qonversion
to Automations
, so if you were using the following methods:
setNotificationsToken
,handleNotification
,getNotificationCustomPayload
,
make sure to make calls from the Automations instance instead of the Qonversion one.
Rest of the changes
Along with the changes described above, there are several technical improvements and other changes in the new major release:
- all the internal classes and extensions are now marked as
internal
, so they won't be accessible from your code and won't pollute your project namespace (note that they are still accessible in java because of interoperability issues, but you should prevent using them as well). All these classes and extensions were moved to theinternal
package to make the library file structure more readable; - the deprecated methods
resetUser
,setUserId
, andhandleNotification(RemoteMessage)
were removed.
resetUser
was deprecated for a long time, and it did nothing, so there is nothing to replace this call with, remove the method if you were still using it for some reason.setUserId
should be replaced with thesetProperty
call withQUserProperties.CustomUserId
parameter. Instead of using thehandleNotification
method, acceptingRemoteMessage
, call the method of the same name, accepting the data map (RemoteMessage.data
). Also note that thehandleNotification(Map<String, String>)
method was moved to theAutomations
class, as described above; - the
firebase-messaging
dependency causing resolution collisions was removed; - the
experiments
method was removed - we are now working on a new design of A/B experiments; QEntitlementsCacheLifetime
enum values are rewritten in CamelCase to match the rest code style;- the
AttributionSource
enum was renamed toQAttributionProvider
and moved to thedto
package; - the
UserProperties
enum was renamed to theQUserProperty
enum and moved to thedto
package; - the
checkTrialIntroEligibilityForProductIds
method was shortened tocheckTrialIntroEligibility
; - added the new method
userInfo
, which returns the information about the current Qonversion user. Now it contains internal Qonversion and identity identifiers. The user info may be extended in future releases; - added new enum values -
QOfferingTag.Unknown
andQTrialDuration.Unknown
, which are used when parsing fails.QTrialDuration.Unknown
is now a default value for theQProduct.trialDuration
field, which is no longer nullable.
Updated about 2 years ago