Миграция Adapty iOS SDK на v3.3
Adapty SDK 3.3.0 — это мажорный релиз, который принёс ряд улучшений, однако для перехода на него могут потребоваться некоторые шаги по миграции.
- Переименуйте
Adapty.ConfigurationвAdaptyConfiguration. - Переименуйте метод
getViewConfigurationвgetPaywallConfiguration. - Удалите параметры
didCancelPurchaseиpaywallиз SwiftUI, а параметрviewConfigurationпереименуйте вpaywallConfiguration. - Обновите обработку promotional встроенных покупок из App Store, удалив параметр
defermentCompletionиз методаAdaptyDelegate. - Удалите метод
getProductsIntroductoryOfferEligibility. - Обновите конфигурации интеграций для Adjust, AirBridge, Amplitude, AppMetrica, Appsflyer, Branch, Facebook Ads, Firebase and Google Analytics, Mixpanel, OneSignal, Pushwoosh.
- Обновите реализацию режима Observer.
Переименование Adapty.Configuration в AdaptyConfiguration
Обновите код активации Adapty iOS SDK следующим образом:
Переименование метода getViewConfiguration в getPaywallConfiguration
Обновите название метода для получения viewConfiguration пейвола:
guard paywall.hasViewConfiguration else {
// use your custom logic
return
}
do {
- let paywallConfiguration = try await AdaptyUI.getViewConfiguration(
+ let paywallConfiguration = try await AdaptyUI.getPaywallConfiguration(
forPaywall: paywall
)
// use loaded configuration
} catch {
// handle the error
}
Подробнее о методе читайте в разделе Получение конфигурации представления пейвола, созданного в Paywall Builder.
Изменения параметров в SwiftUI
В SwiftUI внесены следующие изменения:
- Параметр
didCancelPurchaseудалён. Используйте вместо негоdidFinishPurchase. - Метод
.paywall()больше не принимает объект пейвола. - Параметр
paywallConfigurationзаменил параметрviewConfiguration.
Обновите свой код следующим образом:
@State var paywallPresented = false
var body: some View {
Text("Hello, AdaptyUI!")
.paywall(
isPresented: $paywallPresented,
- paywall: <paywall object>,
- viewConfiguration: <LocalizedViewConfiguration>,
+ paywallConfiguration: <AdaptyUI.PaywallConfiguration>,
didPerformAction: { action in
switch action {
case .close:
paywallPresented = false
default:
// Handle other actions
break
}
},
- didFinishPurchase: { product, profile in paywallPresented = false },
+ didFinishPurchase: { product, purchaseResult in /* handle the result*/ },
didFailPurchase: { product, error in /* handle the error */ },
didFinishRestore: { profile in /* check access level and dismiss */ },
didFailRestore: { error in /* handle the error */ },
didFailRendering: { error in paywallPresented = false }
- didCancelPurchase: { product in /* handle the result*/}
)
}
Обновление обработки promotional in-app purchases из App Store
Обновите обработку promotional in-app purchases из App Store, удалив параметр defermentCompletion из метода AdaptyDelegate, как показано в примере ниже:
final class YourAdaptyDelegateImplementation: AdaptyDelegate {
nonisolated func shouldAddStorePayment(for product: AdaptyDeferredProduct) -> Bool {
// 1a.
// Return `true` to continue the transaction in your app.
// 1b.
// Store the product object and return `false` to defer or cancel the transaction.
false
}
// 2. Continue the deferred purchase later on by passing the product to `makePurchase`
func continueDeferredPurchase() async {
let storedProduct: AdaptyDeferredProduct = // get the product object from the 1b.
do {
try await Adapty.makePurchase(product: storedProduct)
} catch {
// handle the error
}
}
}
Удаление метода getProductsIntroductoryOfferEligibility
До версии Adapty iOS SDK 3.3.0 объект продукта всегда включал офферы вне зависимости от того, имел ли пользователь право на их использование. Вам приходилось вручную проверять право доступа перед использованием оффера.
Теперь объект продукта включает оффер только в том случае, если пользователь имеет на него право. Это означает, что проверка права доступа больше не нужна — если оффер присутствует, пользователь имеет на него право.
Если вы всё же хотите просматривать офферы для пользователей, не имеющих права доступа, обращайтесь к sk1Product и sk2Product.
Обновление конфигурации SDK для сторонних интеграций
Начиная с Adapty iOS SDK 3.3.0, мы обновили публичный API метода updateAttribution. Ранее он принимал словарь [AnyHashable: Any], позволяя передавать объекты атрибуции напрямую из различных сервисов. Теперь требуется [String: any Sendable], поэтому перед передачей необходимо конвертировать объекты атрибуции.
Чтобы интеграции корректно работали с Adapty iOS SDK 3.3.0 и выше, обновите конфигурации SDK для перечисленных ниже интеграций согласно соответствующим разделам.
Adjust
Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе настройка SDK для интеграции с Adjust.
AirBridge
Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе Настройка SDK для интеграции AirBridge.
import AirBridge
- let builder = AdaptyProfileParameters.Builder()
- .with(airbridgeDeviceId: AirBridge.deviceUUID())
-
- Adapty.updateProfile(params: builder.build())
+ do {
+ try await Adapty.setIntegrationIdentifier(
+ key: "airbridge_device_id",
+ value: AirBridge.deviceUUID()
+ )
+ } catch {
+ // handle the error
+ }
Amplitude
Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе настройка SDK для интеграции с Amplitude.
import Amplitude
- let builder = AdaptyProfileParameters.Builder()
- .with(amplitudeUserId: Amplitude.instance().userId)
- .with(amplitudeDeviceId: Amplitude.instance().deviceId)
-
- Adapty.updateProfile(params: builder.build())
+ do {
+ try await Adapty.setIntegrationIdentifier(
+ key: "amplitude_user_id",
+ value: Amplitude.instance().userId
+ )
+ try await Adapty.setIntegrationIdentifier(
+ key: "amplitude_device_id",
+ value: Amplitude.instance().deviceId
+ )
+ } catch {
+ // handle the error
+ }
AppMetrica
Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе Настройка SDK для интеграции с AppMetrica.
import AppMetricaCore
- if let deviceID = AppMetrica.deviceID {
- let builder = AdaptyProfileParameters.Builder()
- .with(appmetricaDeviceId: deviceID)
- .with(appmetricaProfileId: "YOUR_ADAPTY_CUSTOMER_USER_ID")
-
- Adapty.updateProfile(params: builder.build())
- }
+ if let deviceID = AppMetrica.deviceID {
+ do {
+ try await Adapty.setIntegrationIdentifier(
+ key: "appmetrica_device_id",
+ value: deviceID
+ )
+ try await Adapty.setIntegrationIdentifier(
+ key: "appmetrica_profile_id",
+ value: "YOUR_ADAPTY_CUSTOMER_USER_ID"
+ )
+ } catch {
+ // handle the error
+ }
+ }
AppsFlyer
Обновите код мобильного приложения, как показано ниже. Полный пример кода можно найти в разделе Настройка SDK для интеграции с AppsFlyer.
class YourAppsFlyerLibDelegateImplementation {
// Find your implementation of AppsFlyerLibDelegate
// and update onConversionDataSuccess method:
func onConversionDataSuccess(_ conversionInfo: [AnyHashable : Any]) {
let uid = AppsFlyerLib.shared().getAppsFlyerUID()
- Adapty.updateAttribution(
- conversionInfo.toSendableDict(),
- source: .appsflyer,
- networkUserId: uid
- )
+ Adapty.setIntegrationIdentifier(key: "appsflyer_id", value: uid)
+ Adapty.updateAttribution(conversionInfo, source: "appsflyer")
}
}
Branch
Обновите код вашего мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе Настройка SDK для интеграции с Branch.
class YourBranchImplementation {
func initializeBranch() {
// Pass the attribution you receive from the initializing method of Branch iOS SDK to Adapty.
Branch.getInstance().initSession(launchOptions: launchOptions) { (data, error) in
- if let data = data?.toSendableDict() {
- Adapty.updateAttribution(data, source: .branch)
- }
+ if let data {
+ Adapty.updateAttribution(data, source: "branch")
+ }
}
}
}
Facebook Ads
Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе настройка SDK для интеграции с Facebook Ads.
import FacebookCore
- let builder = AdaptyProfileParameters.Builder()
- .with(facebookAnonymousId: AppEvents.shared.anonymousID)
-
- do {
- try Adapty.updateProfile(params: builder.build())
- } catch {
- // handle the error
- }
+ do {
+ try await Adapty.setIntegrationIdentifier(
+ key: "facebook_anonymous_id",
+ value: AppEvents.shared.anonymousID
+ )
+ } catch {
+ // handle the error
+ }
Firebase и Google Analytics
Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе Настройка SDK для интеграции с Firebase и Google Analytics.
import FirebaseCore
import FirebaseAnalytics
FirebaseApp.configure()
- if let appInstanceId = Analytics.appInstanceID() {
- let builder = AdaptyProfileParameters.Builder()
- .with(firebaseAppInstanceId: appInstanceId)
- Adapty.updateProfile(params: builder.build()) { error in
- // handle error
- }
- }
+ if let appInstanceId = Analytics.appInstanceID() {
+ do {
+ try await Adapty.setIntegrationIdentifier(
+ key: "firebase_app_instance_id",
+ value: appInstanceId
+ )
+ } catch {
+ // handle the error
+ }
+ }
Mixpanel
Обновите код мобильного приложения, как показано ниже. Полный пример кода можно найти в разделе Настройка SDK для интеграции с Mixpanel.
import Mixpanel
- let builder = AdaptyProfileParameters.Builder()
- .with(mixpanelUserId: Mixpanel.mainInstance().distinctId)
-
- do {
- try await Adapty.updateProfile(params: builder.build())
- } catch {
- // handle the error
- }
+ do {
+ try await Adapty.setIntegrationIdentifier(
+ key: "mixpanel_user_id",
+ value: Mixpanel.mainInstance().distinctId
+ )
+ } catch {
+ // handle the error
+ }
OneSignal
Обновите код мобильного приложения, как показано ниже. Полный пример кода можно найти в разделе Настройка SDK для интеграции с OneSignal.
// PlayerID (pre-v5 OneSignal SDK)
// in your OSSubscriptionObserver implementation
func onOSSubscriptionChanged(_ stateChanges: OSSubscriptionStateChanges) {
if let playerId = stateChanges.to.userId {
- let params = AdaptyProfileParameters.Builder()
- .with(oneSignalPlayerId: playerId)
- .build()
-
- Adapty.updateProfile(params:params) { error in
- // check error
- }
+ Task {
+ try await Adapty.setIntegrationIdentifier(
+ key: "one_signal_player_id",
+ value: playerId
+ )
+ }
}
}
// SubscriptionID (v5+ OneSignal SDK)
OneSignal.Notifications.requestPermission({ accepted in
- let id = OneSignal.User.pushSubscription.id
-
- let builder = AdaptyProfileParameters.Builder()
- .with(oneSignalSubscriptionId: id)
-
- Adapty.updateProfile(params: builder.build())
+ Task {
+ try await Adapty.setIntegrationIdentifier(
+ key: "one_signal_subscription_id",
+ value: OneSignal.User.pushSubscription.id
+ )
+ }
}, fallbackToSettings: true)
Pushwoosh
Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе Настройка SDK для интеграции с Pushwoosh.
- let params = AdaptyProfileParameters.Builder()
- .with(pushwooshHWID: Pushwoosh.sharedInstance().getHWID())
- .build()
-
- Adapty.updateProfile(params: params) { error in
- // handle the error
- }
+ do {
+ try await Adapty.setIntegrationIdentifier(
+ key: "pushwoosh_hwid",
+ value: Pushwoosh.sharedInstance().getHWID()
+ )
+ } catch {
+ // handle the error
+ }
Обновление реализации режима Observer
Обновите способ привязки пейволов к транзакциям. Раньше для назначения variationId использовался метод setVariationId. Теперь можно передавать variationId напрямую при записи транзакции с помощью нового метода reportTransaction. Ознакомьтесь с итоговым примером кода в разделе Привязка пейволов к транзакциям покупок в режиме Observer.
Не забудьте зафиксировать транзакцию с помощью метода reportTransaction. Если пропустить этот шаг, Adapty не распознает транзакцию, не предоставит уровни доступа, не включит её в аналитику и не передаст в интеграции. Этот шаг обязателен!
- let variationId = paywall.variationId
-
- // There are two overloads: for StoreKit 1 and StoreKit 2
- Adapty.setVariationId(variationId, forPurchasedTransaction: transaction) { error in
- if error == nil {
- // successful binding
- }
- }
+ do {
+ // every time when calling transaction.finish()
+ try await Adapty.reportTransaction(transaction, withVariationId: <YOUR_PAYWALL_VARIATION_ID>)
+ } catch {
+ // handle the error
+ }