Миграция Adapty Android SDK на v3.3

Adapty SDK 3.3.0 — это мажорный релиз, который принёс ряд улучшений, однако для перехода на него могут потребоваться дополнительные шаги миграции.

  1. Обновите способ обработки покупок в пейволах, созданных без Paywall Builder. Перестаньте обрабатывать коды ошибок USER_CANCELED и PENDING_PURCHASE. Отменённая покупка больше не считается ошибкой и теперь будет отображаться в результатах покупки без ошибок.
  2. Замените события onPurchaseCanceled и onPurchaseSuccess новым событием onPurchaseFinished для пейволов, созданных с помощью Paywall Builder. Это изменение связано с той же причиной: отменённые покупки больше не считаются ошибками и будут включены в результаты покупки без ошибок.
  3. Измените сигнатуру метода onAwaitingSubscriptionUpdateParams для пейволов Paywall Builder.
  4. Обновите метод, используемый для предоставления резервных пейволов, если вы передаёте URI файла напрямую.
  5. Обновите конфигурации интеграций для Adjust, AirBridge, Amplitude, AppMetrica, Appsflyer, Branch, Facebook Ads, Firebase и Google Analytics, Mixpanel, OneSignal, Pushwoosh.

Обновление процесса покупки

Ранее отменённые и ожидающие покупки считались ошибками и возвращали коды USER_CANCELED и PENDING_PURCHASE соответственно.

Теперь для обозначения отменённых, успешных и ожидающих покупок используется новый класс AdaptyPurchaseResult. Обновите код покупки следующим образом:

Adapty.makePurchase(activity, product) { result ->
     when (result) {
         is AdaptyResult.Success -> {
-            val info = result.value
-            val profile = info?.profile
-        
-            if (profile?.accessLevels?.get("YOUR_ACCESS_LEVEL")?.isActive == true) {
-                // Grant access to the paid features
-            }
+            when (val purchaseResult = result.value) {
+                is AdaptyPurchaseResult.Success -> {
+                    val profile = purchaseResult.profile
+                    if (profile.accessLevels["YOUR_ACCESS_LEVEL"]?.isActive == true) {
+                        // Grant access to the paid features
+                    }
+                }
+
+                is AdaptyPurchaseResult.UserCanceled -> {
+                    // Handle the case where the user canceled the purchase
+                }
+
+                is AdaptyPurchaseResult.Pending -> {
+                    // Handle deferred purchases (e.g., the user will pay offline with cash
+                }
+            }
         }
         is AdaptyResult.Error -> {
             val error = result.error
             // Handle the error
         }
     }
 }

Полный пример кода смотрите на странице Совершение покупок в мобильном приложении.

Изменение событий покупки в Paywall Builder

  1. Добавьте событие onPurchaseFinished:
    + public override fun onPurchaseFinished(
    +     purchaseResult: AdaptyPurchaseResult,
    +     product: AdaptyPaywallProduct,
    +     context: Context,
    + ) {
    +    when (purchaseResult) {
    +        is AdaptyPurchaseResult.Success -> {
    +            // Grant access to the paid features
    +        }
    +        is AdaptyPurchaseResult.UserCanceled -> {
    +            // Handle the case where the user canceled the purchase
    +        }
    +        is AdaptyPurchaseResult.Pending -> {
    +            // Handle deferred purchases (e.g., the user will pay offline with cash)
    +        }
    +    }
    + }

Для полного примера кода ознакомьтесь с разделом Успешная, отменённая или ожидающая покупка и описанием события.

  1. Удалите обработку события onPurchaseCancelled:

    - public override fun onPurchaseCanceled(
    -     product: AdaptyPaywallProduct,
    -     context: Context,
    - ) {}
  2. Удалите onPurchaseSuccess:

    
    - public override fun onPurchaseSuccess(
    -     profile: AdaptyProfile?,
    -     product: AdaptyPaywallProduct,
    -   context: Context,
    - ) {
    -     // Your logic on successful purchase
    - }

Изменение сигнатуры метода onAwaitingSubscriptionUpdateParams

Теперь, если новая подписка приобретается, пока другая ещё активна, вызывайте onSubscriptionUpdateParamsReceived(AdaptySubscriptionUpdateParameters...)), если новая подписка должна заменить текущую активную, или onSubscriptionUpdateParamsReceived(null), если активная подписка должна оставаться активной, а новая — добавиться отдельно:

- public override fun onAwaitingSubscriptionUpdateParams(
-     product: AdaptyPaywallProduct,
-     context: Context,
- ): AdaptySubscriptionUpdateParameters? {
-     return AdaptySubscriptionUpdateParameters(...)
- }
+ public override fun onAwaitingSubscriptionUpdateParams(
+     product: AdaptyPaywallProduct,
+     context: Context,
+     onSubscriptionUpdateParamsReceived: SubscriptionUpdateParamsCallback,
+ ) {
+     onSubscriptionUpdateParamsReceived(AdaptySubscriptionUpdateParameters(...))
+ }

Смотрите раздел документации Обновление подписки с финальным примером кода.

Обновление передачи резервных пейволов

Если вы передаёте URI файла для предоставления резервных пейволов, обновите этот код следующим образом:

Обновление конфигурации SDK сторонних интеграций

Чтобы интеграции корректно работали с Adapty Android SDK 3.3.0 и выше, обновите конфигурации SDK для следующих интеграций, как описано в разделах ниже.

Adjust

Обновите код вашего мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе Настройка SDK для интеграции с Adjust.

AirBridge

Обновите код вашего мобильного приложения, как показано ниже. Полный пример кода можно найти в разделе Настройка SDK для интеграции с AirBridge.

 Airbridge.getDeviceInfo().getUUID(object: AirbridgeCallback.SimpleCallback<String>() {
     override fun onSuccess(result: String) {
-         val params = AdaptyProfileParameters.Builder()
-             .withAirbridgeDeviceId(result)
-             .build()
-         Adapty.updateProfile(params) { error ->
-             if (error != null) {
-                 // Handle the error
-             }
-         }
+         Adapty.setIntegrationIdentifier("airbridge_device_id", result) { error ->
+             if (error != null) {
+                 // Handle the error
+             }
+         }
     }
     override fun onFailure(throwable: Throwable) {
     }
 })

Amplitude

Обновите код своего мобильного приложения, как показано ниже. Полный пример кода см. в разделе настройка SDK для интеграции с Amplitude.

 // For Amplitude maintenance SDK (obsolete)
 val amplitude = Amplitude.getInstance()
 val amplitudeDeviceId = amplitude.getDeviceId()
 val amplitudeUserId = amplitude.getUserId()

 //for actual Amplitude Kotlin SDK
 val amplitude = Amplitude(
     Configuration(
         apiKey = AMPLITUDE_API_KEY,
         context = applicationContext
     )
 )
 val amplitudeDeviceId = amplitude.store.deviceId
 val amplitudeUserId = amplitude.store.userId

 //

- val params = AdaptyProfileParameters.Builder()
-     .withAmplitudeDeviceId(amplitudeDeviceId)
-     .withAmplitudeUserId(amplitudeUserId)
-     .build()
- Adapty.updateProfile(params) { error ->
-     if (error != null) {
-         // Handle the error
-     }
- }

+ Adapty.setIntegrationIdentifier("amplitude_user_id", amplitudeUserId) { error ->
+     if (error != null) {
+         // Handle the error
+     }
+ }

+ Adapty.setIntegrationIdentifier("amplitude_device_id", amplitudeDeviceId) { error ->
+     if (error != null) {
+         // Handle the error
+     }
+ }

AppMetrica

Обновите код мобильного приложения, как показано ниже. Полный пример кода можно найти в разделе Настройка SDK для интеграции с AppMetrica.

 val startupParamsCallback = object: StartupParamsCallback {
     override fun onReceive(result: StartupParamsCallback.Result?) {
         val deviceId = result?.deviceId ?: return

-        val params = AdaptyProfileParameters.Builder()
-            .withAppmetricaDeviceId(deviceId)
-            .withAppmetricaProfileId("YOUR_ADAPTY_CUSTOMER_USER_ID")
-            .build()
-        Adapty.updateProfile(params) { error ->
-            if (error != null) {
-                // Handle the error
-            }
-        }

+        Adapty.setIntegrationIdentifier("appmetrica_device_id", deviceId) { error ->
+            if (error != null) {
+                // Handle the error
+            }
+        }
+        
+        Adapty.setIntegrationIdentifier("appmetrica_profile_id", "YOUR_ADAPTY_CUSTOMER_USER_ID") { error ->
+            if (error != null) {
+                // Handle the error
+            }
+        }
     }

     override fun onRequestError(
         reason: StartupParamsCallback.Reason,
         result: StartupParamsCallback.Result?
     ) {
         // Handle the error
     }
 }

 AppMetrica.requestStartupParams(context, startupParamsCallback, listOf(StartupParamsCallback.APPMETRICA_DEVICE_ID))

AppsFlyer

Обновите код своего мобильного приложения, как показано ниже. Полный пример кода можно найти в разделе настройка SDK для интеграции с AppsFlyer.

 val conversionListener: AppsFlyerConversionListener = object : AppsFlyerConversionListener {
     override fun onConversionDataSuccess(conversionData: Map<String, Any>) {
-        Adapty.updateAttribution(
-            conversionData,
-            AdaptyAttributionSource.APPSFLYER,
-            AppsFlyerLib.getInstance().getAppsFlyerUID(context)
-        ) { error ->
-            if (error != null) {
-                // Handle the error
-            }
-        }

+        val uid = AppsFlyerLib.getInstance().getAppsFlyerUID(context)
+        Adapty.setIntegrationIdentifier("appsflyer_id", uid) { error ->
+            if (error != null) {
+                // Handle the error
+            }
+        }
+        Adapty.updateAttribution(conversionData, "appsflyer") { error ->
+            if (error != null) {
+                // Handle the error
+            }
+        }
     }
 }

Branch

Обновите код своего мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе Настройка SDK для интеграции с Branch.

// Login and update attribution
 Branch.getAutoInstance(this)
   .setIdentity("YOUR_USER_ID") { referringParams, error ->
       referringParams?.let { data ->
-            Adapty.updateAttribution(data, AdaptyAttributionSource.BRANCH) { error ->
-                if (error != null) {
-                    // Handle the error
-                }
-            }
+            Adapty.updateAttribution(data, "branch") { error ->
+                if (error != null) {
+                    // Handle the error
+                }
+            }
       }
   }

 // Logout
 Branch.getAutoInstance(context).logout()

Facebook Ads

Обновите код мобильного приложения, как показано ниже. Полный пример кода можно найти в разделе настройка SDK для интеграции с Facebook Ads.

- val builder = AdaptyProfileParameters.Builder()
-     .withFacebookAnonymousId(AppEventsLogger.getAnonymousAppDeviceGUID(context))
-   
- Adapty.updateProfile(builder.build()) { error ->
-     if (error != null) {
-        // Handle the error
-     }
- }

+ Adapty.setIntegrationIdentifier(
+     "facebook_anonymous_id",
+     AppEventsLogger.getAnonymousAppDeviceGUID(context)
+ ) { error ->
+     if (error != null) {
+        // Handle the error
+     }
+ }

Firebase и Google Analytics

Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе Настройка SDK для интеграции с Firebase и Google Analytics.

Mixpanel

Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в настройке SDK для интеграции с Mixpanel.

- val params = AdaptyProfileParameters.Builder()
-     .withMixpanelUserId(mixpanelAPI.distinctId)
-     .build()
-
- Adapty.updateProfile(params) { error ->
-     if (error != null) {
-         // Handle the error
-     }
- }

+ Adapty.setIntegrationIdentifier("mixpanel_user_id", mixpanelAPI.distinctId) { error ->
+     if (error != null) {
+         // Handle the error
+     }
+ }

OneSignal

Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе Настройка SDK для интеграции с OneSignal.

Pushwoosh

Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе Настройка SDK для интеграции с Pushwoosh.