ÿÿ Adapty iOS SDK v3.3 ã¸ã®ç§»è¡Œ | Adapty ドキュメント

Adapty iOS SDK ã‚’ v3.3 ã«ç§»è¡Œã™ã‚‹

Adapty SDK 3.3.0 ã¯ãƒ¡ã‚¸ãƒ£ãƒ¼ãƒªãƒªãƒ¼ã‚¹ã§ã‚りã€ã„ãã¤ã‹ã®æ”¹å–„ãŒåŠ ãˆã‚‰ã‚Œã¦ã„ã¾ã™ã€‚ãŸã ã—ã€ä¸€éƒ¨ã®ç§»è¡Œæ‰‹é †ãŒå¿…è¦ã«ãªã‚‹å ´åˆãŒã‚りã¾ã™ã€‚

  1. Adapty.Configuration ã‚’ AdaptyConfiguration ã«ãƒªãƒãƒ¼ãƒ ã™ã‚‹ã€‚
  2. getViewConfiguration メソッドを getPaywallConfiguration ã«ãƒªãƒãƒ¼ãƒ ã™ã‚‹ã€‚
  3. SwiftUI ã‹ã‚‰ didCancelPurchase 㨠paywall パラメータを削除ã—ã€viewConfiguration パラメータを paywallConfiguration ã«ãƒªãƒãƒ¼ãƒ ã™ã‚‹ã€‚
  4. AdaptyDelegate メソッドã‹ã‚‰ defermentCompletion パラメータを削除ã—ã¦ã€App Store ã‹ã‚‰ã®ãƒ—ロモーション用アプリ内課金ã®å‡¦ç†æ–¹æ³•ã‚’æ›´æ–°ã™ã‚‹ã€‚
  5. getProductsIntroductoryOfferEligibility メソッドを削除ã™ã‚‹ã€‚
  6. Adjustã€AirBridgeã€Amplitudeã€AppMetricaã€Appsflyerã€Branchã€Facebook Adsã€Firebase 㨠Google Analyticsã€Mixpanelã€OneSignalã€Pushwoosh ã®ã‚¤ãƒ³ãƒ†ã‚°ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³è¨­å®šã‚’æ›´æ–°ã™ã‚‹ã€‚
  7. オブザーãƒãƒ¼ãƒ¢ãƒ¼ãƒ‰ã®å®Ÿè£…ã‚’æ›´æ–°ã™ã‚‹ã€‚

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
}

メソッドã®è©³ç´°ã«ã¤ã„ã¦ã¯ã€ãƒšã‚¤ã‚¦ã‚©ãƒ¼ãƒ«ãƒ“ルダーã§ä½œæˆã—ãŸãƒšã‚¤ã‚¦ã‚©ãƒ¼ãƒ«ã®ãƒ“ュー設定をå–å¾—ã™ã‚‹ã‚’ã”覧ãã ã•ã„。

SwiftUI ã®ãƒ‘ラメータを変更ã™ã‚‹

SwiftUI ã«ä»¥ä¸‹ã®å¤‰æ›´ãŒåŠ ãˆã‚‰ã‚Œã¦ã„ã¾ã™ï¼š

  1. didCancelPurchase パラメータãŒå‰Šé™¤ã•れã¾ã—ãŸã€‚代ã‚り㫠didFinishPurchase を使用ã—ã¦ãã ã•ã„。
  2. .paywall() メソッドã¯ãƒšã‚¤ã‚¦ã‚©ãƒ¼ãƒ«ã‚ªãƒ–ジェクトをå—ã‘付ã‘ãªããªã‚Šã¾ã—ãŸã€‚
  3. 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*/}

      )
}

App Store ã‹ã‚‰ã®ãƒ—ロモーション用アプリ内課金ã®å‡¦ç†ã‚’æ›´æ–°ã™ã‚‹

以下ã®ä¾‹ã®ã‚ˆã†ã« AdaptyDelegate メソッドã‹ã‚‰ defermentCompletion パラメータを削除ã—ã¦ã€App Store ã‹ã‚‰ã®ãƒ—ロモーション用アプリ内課金ã®å‡¦ç†æ–¹æ³•ã‚’æ›´æ–°ã—ã¦ãã ã•ã„:

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 ã‹ã‚‰ã€updateAttribution メソッドã®å…¬é–‹ API ãŒæ›´æ–°ã•れã¾ã—ãŸã€‚以å‰ã¯ [AnyHashable: Any] 辞書をå—ã‘付ã‘ã¦ãŠã‚Šã€å„サービスã®ã‚¢ãƒˆãƒªãƒ“ューションオブジェクトをãã®ã¾ã¾æ¸¡ã™ã“ã¨ãŒã§ãã¾ã—ãŸã€‚ç¾åœ¨ã¯ [String: any Sendable] ãŒå¿…è¦ãªãŸã‚ã€æ¸¡ã™å‰ã«ã‚¢ãƒˆãƒªãƒ“ューションオブジェクトを変æ›ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚

Adapty iOS SDK 3.3.0 以é™ã§ã‚¤ãƒ³ãƒ†ã‚°ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãŒæ­£å¸¸ã«å‹•作ã™ã‚‹ã‚ˆã†ã€ä»¥ä¸‹ã®ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã«å¾“ã£ã¦å„インテグレーション㮠SDK 設定を更新ã—ã¦ãã ã•ã„。

Adjust

以下ã®ã‚ˆã†ã«ãƒ¢ãƒã‚¤ãƒ«ã‚¢ãƒ—リã®ã‚³ãƒ¼ãƒ‰ã‚’æ›´æ–°ã—ã¦ãã ã•ã„。完全ãªã‚³ãƒ¼ãƒ‰ä¾‹ã«ã¤ã„ã¦ã¯ã€Adjust インテグレーション㮠SDK 設定をã”確èªãã ã•ã„。

AirBridge

以下ã®ã‚ˆã†ã«ãƒ¢ãƒã‚¤ãƒ«ã‚¢ãƒ—リã®ã‚³ãƒ¼ãƒ‰ã‚’æ›´æ–°ã—ã¦ãã ã•ã„。完全ãªã‚³ãƒ¼ãƒ‰ä¾‹ã«ã¤ã„ã¦ã¯ã€AirBridge インテグレーション㮠SDK 設定をã”確èªãã ã•ã„。

 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

以下ã®ã‚ˆã†ã«ãƒ¢ãƒã‚¤ãƒ«ã‚¢ãƒ—リã®ã‚³ãƒ¼ãƒ‰ã‚’æ›´æ–°ã—ã¦ãã ã•ã„。完全ãªã‚³ãƒ¼ãƒ‰ä¾‹ã«ã¤ã„ã¦ã¯ã€Amplitude インテグレーション㮠SDK 設定をã”確èªãã ã•ã„。

 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

以下ã®ã‚ˆã†ã«ãƒ¢ãƒã‚¤ãƒ«ã‚¢ãƒ—リã®ã‚³ãƒ¼ãƒ‰ã‚’æ›´æ–°ã—ã¦ãã ã•ã„。完全ãªã‚³ãƒ¼ãƒ‰ä¾‹ã«ã¤ã„ã¦ã¯ã€AppMetrica インテグレーション㮠SDK 設定をã”確èªãã ã•ã„。

 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

以下ã®ã‚ˆã†ã«ãƒ¢ãƒã‚¤ãƒ«ã‚¢ãƒ—リã®ã‚³ãƒ¼ãƒ‰ã‚’æ›´æ–°ã—ã¦ãã ã•ã„。完全ãªã‚³ãƒ¼ãƒ‰ä¾‹ã«ã¤ã„ã¦ã¯ã€AppsFlyer インテグレーション㮠SDK 設定をã”確èªãã ã•ã„。

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

以下ã®ã‚ˆã†ã«ãƒ¢ãƒã‚¤ãƒ«ã‚¢ãƒ—リã®ã‚³ãƒ¼ãƒ‰ã‚’æ›´æ–°ã—ã¦ãã ã•ã„。完全ãªã‚³ãƒ¼ãƒ‰ä¾‹ã«ã¤ã„ã¦ã¯ã€Branch インテグレーション㮠SDK 設定をã”確èªãã ã•ã„。

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

以下ã®ã‚ˆã†ã«ãƒ¢ãƒã‚¤ãƒ«ã‚¢ãƒ—リã®ã‚³ãƒ¼ãƒ‰ã‚’æ›´æ–°ã—ã¦ãã ã•ã„。完全ãªã‚³ãƒ¼ãƒ‰ä¾‹ã«ã¤ã„ã¦ã¯ã€Facebook Ads インテグレーション㮠SDK 設定をã”確èªãã ã•ã„。

 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

以下ã®ã‚ˆã†ã«ãƒ¢ãƒã‚¤ãƒ«ã‚¢ãƒ—リã®ã‚³ãƒ¼ãƒ‰ã‚’æ›´æ–°ã—ã¦ãã ã•ã„。完全ãªã‚³ãƒ¼ãƒ‰ä¾‹ã«ã¤ã„ã¦ã¯ã€Firebase 㨠Google Analytics インテグレーション㮠SDK 設定をã”確èªãã ã•ã„。

 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

以下ã®ã‚ˆã†ã«ãƒ¢ãƒã‚¤ãƒ«ã‚¢ãƒ—リã®ã‚³ãƒ¼ãƒ‰ã‚’æ›´æ–°ã—ã¦ãã ã•ã„。完全ãªã‚³ãƒ¼ãƒ‰ä¾‹ã«ã¤ã„ã¦ã¯ã€Mixpanel インテグレーション㮠SDK 設定をã”確èªãã ã•ã„。

 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

以下ã®ã‚ˆã†ã«ãƒ¢ãƒã‚¤ãƒ«ã‚¢ãƒ—リã®ã‚³ãƒ¼ãƒ‰ã‚’æ›´æ–°ã—ã¦ãã ã•ã„。完全ãªã‚³ãƒ¼ãƒ‰ä¾‹ã«ã¤ã„ã¦ã¯ã€OneSignal インテグレーション㮠SDK 設定をã”確èªãã ã•ã„。

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

以下ã®ã‚ˆã†ã«ãƒ¢ãƒã‚¤ãƒ«ã‚¢ãƒ—リã®ã‚³ãƒ¼ãƒ‰ã‚’æ›´æ–°ã—ã¦ãã ã•ã„。完全ãªã‚³ãƒ¼ãƒ‰ä¾‹ã«ã¤ã„ã¦ã¯ã€Pushwoosh インテグレーション㮠SDK 設定をã”確èªãã ã•ã„。

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

オブザーãƒãƒ¼ãƒ¢ãƒ¼ãƒ‰ã®å®Ÿè£…ã‚’æ›´æ–°ã™ã‚‹

ペイウォールã¨ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’ç´ä»˜ã‘る方法を更新ã—ã¦ãã ã•ã„。以å‰ã¯ setVariationId メソッドを使用ã—㦠variationId を割り当ã¦ã¦ã„ã¾ã—ãŸã€‚ç¾åœ¨ã¯ã€æ–°ã—ã„ reportTransaction メソッドを使用ã—ã¦ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’記録ã™ã‚‹éš›ã« variationId を直接å«ã‚ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚最終的ãªã‚³ãƒ¼ãƒ‰ä¾‹ã«ã¤ã„ã¦ã¯ã€ã‚ªãƒ–ザーãƒãƒ¼ãƒ¢ãƒ¼ãƒ‰ã§ãƒšã‚¤ã‚¦ã‚©ãƒ¼ãƒ«ã‚’購入トランザクションã«é–¢é€£ä»˜ã‘ã‚‹ã‚’ã”確èªãã ã•ã„。

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