Migrer le SDK Adapty iOS vers v3.3

Adapty SDK 3.3.0 est une version majeure qui apporte plusieurs améliorations nécessitant toutefois quelques étapes de migration de votre côté.

  1. Renommez Adapty.Configuration en AdaptyConfiguration.
  2. Renommez la méthode getViewConfiguration en getPaywallConfiguration.
  3. Supprimez les paramètres didCancelPurchase et paywall de SwiftUI, et renommez le paramètre viewConfiguration en paywallConfiguration.
  4. Mettez à jour la gestion des achats intégrés promotionnels depuis l’App Store en supprimant le paramètre defermentCompletion de la méthode AdaptyDelegate.
  5. Supprimez la méthode getProductsIntroductoryOfferEligibility.
  6. Mettez à jour les configurations d’intégration pour Adjust, AirBridge, Amplitude, AppMetrica, Appsflyer, Branch, Facebook Ads, Firebase et Google Analytics, Mixpanel, OneSignal, Pushwoosh.
  7. Mettez à jour l’implémentation du mode Observateur.

Renommer Adapty.Configuration en AdaptyConfiguration

Mettez à jour le code d’activation du SDK Adapty iOS de la façon suivante :

Renommer la méthode getViewConfiguration en getPaywallConfiguration

Mettez à jour le nom de la méthode pour récupérer la viewConfiguration du paywall :


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
}

Pour plus de détails sur la méthode, consultez Récupérer la configuration de vue d’un paywall conçu avec Paywall Builder.

Mettre à jour les paramètres dans SwiftUI

Les modifications suivantes ont été apportées à SwiftUI :

  1. Le paramètre didCancelPurchase a été supprimé. Utilisez didFinishPurchase à la place.
  2. La méthode .paywall() n’accepte plus d’objet paywall.
  3. Le paramètre paywallConfiguration remplace désormais le paramètre viewConfiguration.

Mettez à jour votre code comme suit :

@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*/}

      )
}

Mettre à jour la gestion des achats intégrés promotionnels depuis l’App Store

Mettez à jour la façon dont vous gérez les achats intégrés promotionnels depuis l’App Store en supprimant le paramètre defermentCompletion de la méthode AdaptyDelegate, comme illustré ci-dessous :

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
        }
    }
}

Supprimer la méthode getProductsIntroductoryOfferEligibility

Avant Adapty iOS SDK 3.3.0, l’objet produit incluait toujours les offres, que l’utilisateur soit éligible ou non. Vous deviez vérifier l’éligibilité manuellement avant d’utiliser l’offre.

Désormais, l’objet produit n’inclut une offre que si l’utilisateur est éligible. Vous n’avez donc plus besoin de vérifier l’éligibilité — si une offre est présente, l’utilisateur est éligible.

Si vous souhaitez tout de même consulter les offres pour les utilisateurs non éligibles, référez-vous à sk1Product et sk2Product.

Mettre à jour la configuration du SDK d’intégration tiers

À partir de l’Adapty iOS SDK 3.3.0, nous avons mis à jour l’API publique de la méthode updateAttribution. Auparavant, elle acceptait un dictionnaire [AnyHashable: Any], ce qui permettait de passer directement des objets d’attribution issus de différents services. Désormais, elle requiert un [String: any Sendable], vous devrez donc convertir les objets d’attribution avant de les passer.

Pour que les intégrations fonctionnent correctement avec l’Adapty iOS SDK 3.3.0 et les versions ultérieures, mettez à jour vos configurations SDK pour les intégrations suivantes comme décrit dans les sections ci-dessous.

Adjust

Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour un exemple de code complet, consultez la configuration du SDK pour l’intégration Adjust.

AirBridge

Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour un exemple de code complet, consultez la configuration du SDK pour l’intégration 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

Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour un exemple de code complet, consultez la configuration du SDK pour l’intégration 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

Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour un exemple de code complet, consultez la configuration du SDK pour l’intégration 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

Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour un exemple de code complet, consultez la configuration du SDK pour l’intégration 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

Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour un exemple de code complet, consultez la configuration du SDK pour l’intégration 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

Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour un exemple de code complet, consultez la configuration du SDK pour l’intégration 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 et Google Analytics

Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour un exemple de code complet, consultez la configuration du SDK pour l’intégration Firebase et 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

Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour un exemple de code complet, consultez la configuration du SDK pour l’intégration 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

Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour un exemple de code complet, consultez la configuration du SDK pour l’intégration 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

Mettez à jour le code de votre application mobile comme indiqué ci-dessous. Pour un exemple de code complet, consultez la configuration du SDK pour l’intégration 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
+ }

Mise à jour de l’implémentation du mode Observer

Mettez à jour la façon dont vous associez les paywalls aux transactions. Auparavant, vous utilisiez la méthode setVariationId pour attribuer le variationId. Désormais, vous pouvez inclure le variationId directement lors de l’enregistrement de la transaction grâce à la nouvelle méthode reportTransaction. Consultez l’exemple de code final dans Associer les paywalls aux transactions d’achat en mode Observer.

Warning

N’oubliez pas d’enregistrer la transaction avec la méthode reportTransaction. Si vous sautez cette étape, Adapty ne reconnaîtra pas la transaction, n’accordera pas de niveaux d’accès, ne l’inclura pas dans les analyses et ne l’enverra pas aux intégrations. Cette étape est indispensable !

- 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
+ }