Adapty iOS SDK'yı v4.0'a Taşıma

Adapty iOS SDK 4.0 (beta), flow’ları tanıtır ve paywall API’lerini buna göre yeniden adlandırır. Yeni API’ler hem yeni Flow Builder hem de mevcut Paywall Builder ile çalışır; Adapty Kontrol Paneli tarafında herhangi bir kurulum değişikliği gerekmez.

Hızlı referans

v3v4
Adapty.getPaywall(placementId:locale:)Adapty.getFlow(placementId:)
AdaptyUI.getPaywallConfiguration(forPaywall:)AdaptyUI.getFlowConfiguration(forFlow:locale:)
Adapty.getPaywallProducts(paywall:)Adapty.getPaywallProducts(flow:)
Adapty.logShowPaywall(_:)Adapty.logShowFlow(_:)
AdaptyPaywallControllerAdaptyFlowController
AdaptyPaywallControllerDelegateAdaptyFlowControllerDelegate
AdaptyUI.paywallController(with:delegate:)AdaptyUI.flowController(with:delegate:)
.paywall() (SwiftUI modifier).flow()
AdaptyPaywallViewAdaptyFlowView
didFailRenderingWith: / didFailRendering:didReceiveError:
didFinishPurchase (isteğe bağlı, başarıda otomatik kapanır)didFinishPurchase (zorunlu, otomatik kapanma yok)
Adapty_KidsMode / AdaptyUI_KidsMode paket ürünleriKidsMode paket trait’i
Adapty.updateAttribution(_:source:) (source: String)Adapty.updateAttribution(_:source:) (source: AdaptyAttributionSource)
Adapty.setIntegrationIdentifier(key:value:)Adapty.setIntegrationIdentifier(_:) (AdaptyIntegrationIdentifier)

Minimum iOS sürümü

Adapty iOS SDK 4.0, minimum deployment target’ı iOS 13.0’dan iOS 15.0’a yükseltiyor. Yükseltmeden önce projenizin iOS Deployment Target’ını 15.0 veya üzerine ayarlayın.

Kurulum: CocoaPods artık desteklenmiyor

Adapty iOS SDK 4.0, CocoaPods desteğini kaldırdı. SDK’yı Swift Package Manager ile yükleyin.

Projeniz hâlâ CocoaPods kullanıyorsa Podfile dosyanızdan Adapty ve AdaptyUI pod’larını kaldırın, pod install çalıştırarak temizleyin, ardından Xcode’da File → Add Package Dependency seçeneğiyle https://github.com/adaptyteam/AdaptySDK-iOS.git adresini kullanarak paketi ekleyin.

Çocuk Modu: ayrı ürünler yerine paket özelliği

v3’te Çocuk Modu’nu, ayrı Adapty_KidsMode ve AdaptyUI_KidsMode paket ürünlerini seçerek ve import’larınızı yeniden adlandırarak etkinleştiriyordunuz. 4.0.0-beta.2 sürümünden itibaren bu ürünler kaldırıldı. Çocuk Modu artık normal Adapty paketinde KidsMode adlı bir Swift paket özelliğidir — etkinleştirdiğinizde tüm SDK genelinde IDFA ve AdSupport derleme dışı bırakılır.

Geçiş yapmak için:

  1. Choose Package Products penceresinde, Adapty_KidsMode ve AdaptyUI_KidsMode yerine standart Adapty ve AdaptyUI ürünlerini seçin.

  2. KidsMode trait’ini etkinleştirin. Xcode 26.4 veya daha yeni bir sürümde, bunu projenizin Package Dependencies görünümündeki AdaptySDK-iOS bağımlılığı için etkinleştirin. Adapty’yi Package.swift dosyasına bağımlılık olarak ekliyorsanız (swift-tools-version 6.1 veya daha yenisi gerekir), orada etkinleştirin:

   .package(
       url: "https://github.com/adaptyteam/AdaptySDK-iOS.git",
       exact: "4.0.0-beta.2",
       traits: ["KidsMode"]
   )
  1. Import’larınızı normal modüllere geri değiştirin:

    - import Adapty_KidsMode
    - import AdaptyUI_KidsMode
    + import Adapty
    + import AdaptyUI

26.4’ten önceki Xcode sürümleri, Xcode projesinde trait’leri arayüzden etkinleştiremez. Bu durumda, KidsMode trait’i etkin olarak Adapty’ye bağımlı küçük bir yerel Swift paketi oluşturun ve uygulama hedefi bu pakete bağımlı olsun.

Kaldırılan API’ler

  • Adapty.getPaywallProductsWithoutDeterminingOffer(paywall:) — kaldırıldı. Artık tüm ürünler teklif bilgisini içerdiğinden, ayrı bir uygunluk kontrolü adımına gerek kalmadı.
  • AdaptyPaywallProductWithoutDeterminingOffer — kaldırıldı. Daha önce bu türü (örneğin didSelectProduct gibi) callback’lere geçiren yapılar artık AdaptyPaywallProduct kullanıyor.

App Store tanıtılan uygulama içi satın almalar geçici olarak kaldırıldı

StoreKit 2 geçişinin bir parçası olarak, Adapty iOS SDK 4.0, App Store tanıtılan uygulama içi satın almalar için desteği kaldırdı. shouldAddStorePayment(for:) delegate metodu ve aldığı AdaptyDeferredProduct türü 4.0’da kullanılamamaktadır.

Bu kaldırma işlemi geçicidir — tanıtılan uygulama içi satın alma desteği daha sonraki bir 4.x sürümünde geri dönecektir. Uygulamanız tanıtılan uygulama içi satın almalara dayanıyorsa, destek geri dönene kadar iOS SDK 3.x sürümünde kalmaya devam edin.

Paywall’ları Getirme

getPaywall + getPaywallConfiguration → getFlow + getFlowConfiguration

Döndürülen türler AdaptyPaywall / AdaptyUI.PaywallConfiguration yerine AdaptyFlow / AdaptyUI.FlowConfiguration olarak değişiyor. locale parametresi fetch çağrısından çıkarılıp getFlowConfiguration üzerine taşınıyor:

- let paywall = try await Adapty.getPaywall(placementId: "YOUR_PLACEMENT_ID", locale: "en")
- let paywallConfiguration = try await AdaptyUI.getPaywallConfiguration(forPaywall: paywall)
+ let flow = try await Adapty.getFlow(placementId: "YOUR_PLACEMENT_ID")
+ let flowConfiguration = try await AdaptyUI.getFlowConfiguration(forFlow: flow, locale: "en")

getPaywallProducts(paywall:) → getPaywallProducts(flow:)

getPaywallProducts artık Adapty.getFlow tarafından döndürülen bir AdaptyFlow alıyor:

- let products = try await Adapty.getPaywallProducts(paywall: paywall)
+ let products = try await Adapty.getPaywallProducts(flow: flow)

Paywall görüntülemelerini takip etme

logShowPaywall(:) → logShowFlow(:)

logShowPaywall, logShowFlow olarak yeniden adlandırıldı ve artık AdaptyPaywall yerine AdaptyFlow alıyor. Olay hâlâ aynı varyasyona karşı kaydedildiği için mevcut dönüşüm hunisi ve A/B testi metrikleri kontrol panelinde herhangi bir değişiklik yapılmadan çalışmaya devam eder.

- try await Adapty.logShowPaywall(paywall)
+ try await Adapty.logShowFlow(flow)

v3’te olduğu gibi, Flow Builder veya Paywall Builder tarafından oluşturulan flow veya paywall’ları görüntülerken bu metodu çağırmanız gerekmez — Adapty bu görüntülemeleri otomatik olarak takip eder.

didFinishPurchase artık zorunlu

v3’te didFinishPurchase isteğe bağlıydı: uygulamazsanız, başarılı bir satın alma işleminin ardından paywall kendiliğinden kapanıyordu. 4.0.0-beta.2 sürümünden itibaren bu varsayılan otomatik kapanma davranışı kaldırıldı; böylece bir flow, başarılı bir satın alma işleminin ardından devam edebilir — örneğin flow’unuzun kalan ekranlarını göstermek için. Satın alma işleminin ardından ne olacağına artık siz karar veriyorsunuz: ekranı kapatabilir ya da flow’un devam etmesi için hiçbir şey yapmayabilirsiniz.

  • UIKit: AdaptyFlowControllerDelegate uyumluları artık didFinishPurchase metodunu uygulamak zorundadır — bu metodun artık varsayılan bir implementasyonu yoktur.
  • SwiftUI: .flow(...) ve AdaptyFlowView(...) içindeki didFinishPurchase closure’ı artık zorunludur (non-optional); bu durum didFailPurchase ve didFinishRestore ile tutarlı hale getirilmiştir.

v3 davranışını korumak için ekranı kendiniz kapatın:

func flowController(
    _ controller: AdaptyFlowController,
    didFinishPurchase product: AdaptyPaywallProduct,
    purchaseResult: AdaptyPurchaseResult
) {
    if !purchaseResult.isPurchaseCancelled {
        controller.dismiss(animated: true)
    }
}

UIKit

AdaptyPaywallController → AdaptyFlowController

Kontrolcü türünü ve fabrika metodunu yeniden adlandırın:

- let controller = try AdaptyUI.paywallController(
-     with: paywallConfiguration,
-     delegate: self
- )
+ let controller = try AdaptyUI.flowController(
+     with: flowConfiguration,
+     delegate: self
+ )

AdaptyPaywallControllerDelegate → AdaptyFlowControllerDelegate

Protokolü yeniden adlandırın ve her metot imzasını güncelleyin. didSelectProduct artık kaldırılan AdaptyPaywallProductWithoutDeterminingOffer yerine AdaptyPaywallProduct alıyor; didFinishPurchase ise artık zorunlu olarak uygulanmalıdır — varsayılan bir implementasyonu kalmadı.

- class YourClass: AdaptyPaywallControllerDelegate {
+ class YourClass: AdaptyFlowControllerDelegate {

-     func paywallControllerDidAppear(_ controller: AdaptyPaywallController) { }
+     func flowControllerDidAppear(_ controller: AdaptyFlowController) { }

-     func paywallControllerDidDisappear(_ controller: AdaptyPaywallController) { }
+     func flowControllerDidDisappear(_ controller: AdaptyFlowController) { }

-     func paywallController(_ controller: AdaptyPaywallController,
-                            didPerform action: AdaptyUI.Action) { }
+     func flowController(_ controller: AdaptyFlowController,
+                         didPerform action: AdaptyUI.Action) { }

-     func paywallController(_ controller: AdaptyPaywallController,
-                            didSelectProduct product: AdaptyPaywallProductWithoutDeterminingOffer) { }
+     func flowController(_ controller: AdaptyFlowController,
+                         didSelectProduct product: AdaptyPaywallProduct) { }

-     func paywallController(_ controller: AdaptyPaywallController,
-                            didStartPurchase product: AdaptyPaywallProduct) { }
+     func flowController(_ controller: AdaptyFlowController,
+                         didStartPurchase product: AdaptyPaywallProduct) { }

-     func paywallController(_ controller: AdaptyPaywallController,
-                            didFinishPurchase product: AdaptyPaywallProduct,
-                            purchaseResult: AdaptyPurchaseResult) { }
+     func flowController(_ controller: AdaptyFlowController,
+                         didFinishPurchase product: AdaptyPaywallProduct,
+                         purchaseResult: AdaptyPurchaseResult) { }

-     func paywallController(_ controller: AdaptyPaywallController,
-                            didFailPurchase product: AdaptyPaywallProduct,
-                            error: AdaptyError) { }
+     func flowController(_ controller: AdaptyFlowController,
+                         didFailPurchase product: AdaptyPaywallProduct,
+                         error: AdaptyError) { }

-     func paywallControllerDidStartRestore(_ controller: AdaptyPaywallController) { }
+     func flowControllerDidStartRestore(_ controller: AdaptyFlowController) { }

-     func paywallController(_ controller: AdaptyPaywallController,
-                            didFinishRestoreWith profile: AdaptyProfile) { }
+     func flowController(_ controller: AdaptyFlowController,
+                         didFinishRestoreWith profile: AdaptyProfile) { }

-     func paywallController(_ controller: AdaptyPaywallController,
-                            didFailRestoreWith error: AdaptyError) { }
+     func flowController(_ controller: AdaptyFlowController,
+                         didFailRestoreWith error: AdaptyError) { }

-     func paywallController(_ controller: AdaptyPaywallController,
-                            didFailRenderingWith error: AdaptyUIError) { }
+     func flowController(_ controller: AdaptyFlowController,
+                         didReceiveError error: AdaptyUIError) { }

-     func paywallController(_ controller: AdaptyPaywallController,
-                            didFailLoadingProductsWith error: AdaptyError) -> Bool { }
+     func flowController(_ controller: AdaptyFlowController,
+                         didFailLoadingProductsWith error: AdaptyError) -> Bool { }

-     func paywallController(_ controller: AdaptyPaywallController,
-                            didPartiallyLoadProducts failedIds: [String]) { }
+     func flowController(_ controller: AdaptyFlowController,
+                         didPartiallyLoadProducts failedIds: [String]) { }

-     func paywallController(_ controller: AdaptyPaywallController,
-                            didFinishWebPaymentNavigation product: AdaptyPaywallProduct?,
-                            error: AdaptyError?) { }
+     func flowController(_ controller: AdaptyFlowController,
+                         didFinishWebPaymentNavigation product: AdaptyPaywallProduct?,
+                         error: AdaptyError?) { }
 }

SwiftUI

.paywall() modifier → .flow()

Modifier adını değiştirin, yapılandırma parametre adını güncelleyin ve artık zorunlu olan didFinishPurchase closure’ını ekleyin:

 @State var flowPresented = false // rename freely — the variable name is your choice

 var body: some View {
     Text("Hello, AdaptyUI!")
-        .paywall(
+        .flow(
             isPresented: $flowPresented,
-            paywallConfiguration: paywallConfiguration,
+            flowConfiguration: flowConfiguration,
+            didFinishPurchase: { product, purchaseResult in /* dismiss, or do nothing to let the flow continue */ },
             didFailPurchase: { product, error in /* handle the error */ },
             didFinishRestore: { profile in /* check access level and dismiss */ },
             didFailRestore: { error in /* handle the error */ },
-            didFailRendering: { error in flowPresented = false }
+            didReceiveError: { error in flowPresented = false }
         )
 }

Yeniden adlandırılan callback, didFailRendering’in tetiklendiği tüm render hatalarında olduğu gibi, flow script’inden gelen yeni çalışma zamanı hatalarında da (AdaptyUIError kodu 4105.jsException olan JavaScript istisnaları) tetiklenir. Mevcut handler gövdelerinde kod değişikliği gerekmez — yalnızca parametreyi yeniden adlandırın.

AdaptyPaywallView → AdaptyFlowView

Görünümü yeniden adlandırın, yapılandırma parametresini güncelleyin, artık zorunlu olan didFinishPurchase closure’ını ekleyin ve varsa didSelectProduct closure’ını güncelleyin — artık kaldırılan AdaptyPaywallProductWithoutDeterminingOffer yerine AdaptyPaywallProduct alıyor:

- AdaptyPaywallView(
-     paywallConfiguration: paywallConfiguration,
-     didSelectProduct: { product: AdaptyPaywallProductWithoutDeterminingOffer in /* handle */ },
+ AdaptyFlowView(
+     flowConfiguration: flowConfiguration,
+     didSelectProduct: { product: AdaptyPaywallProduct in /* handle */ },
+     didFinishPurchase: { product, purchaseResult in /* dismiss, or do nothing to let the flow continue */ },
     didFailPurchase: { product, error in /* handle the error */ },
     didFinishRestore: { profile in /* check access level and dismiss */ },
     didFailRestore: { error in /* handle the error */ },
-    didFailRendering: { error in /* handle the error */ }
+    didReceiveError: { error in /* handle the error */ }
 )

AdaptyUI özel varlıklar

AdaptyUICustomVideoAsset

Mevcut her çağrı noktasını etkileyen iki değişiklik:

  • .player artık AVQueuePlayer yerine AVPlayer alıyor.
  • Her case’e sonda resolution: CGSize? parametresi eklendi. Mevcut davranışı korumak için nil geçin ya da video yüklenmeden önce yerleşim alanını ayırt etmesi (en-boy oranı = width / height) için gerçek piksel boyutunu belirtin.
- case file(url: URL, preview: AdaptyUICustomImageAsset?)
- case remote(url: URL, preview: AdaptyUICustomImageAsset?)
- case player(item: AVPlayerItem, player: AVQueuePlayer, preview: AdaptyUICustomImageAsset?)
+ case file(url: URL, preview: AdaptyUICustomImageAsset?, resolution: CGSize?)
+ case remote(url: URL, preview: AdaptyUICustomImageAsset?, resolution: CGSize?)
+ case player(item: AVPlayerItem, player: AVPlayer, preview: AdaptyUICustomImageAsset?, resolution: CGSize?)

Attribution ve entegrasyon tanımlayıcıları

updateAttribution(_:source:)

source parametresi String yerine yeni AdaptyAttributionSource türünü kullanıyor; daha önce iç içe olan AdaptyProfile.AttributionSource ise üst düzey AdaptyAttributionSource olarak yeniden adlandırıldı. Önceden tanımlanmış kaynaklardan birini kullanabilir ya da başka bir kaynak için string literal geçirebilirsiniz — AdaptyAttributionSource, ExpressibleByStringLiteral protokolüne uyduğundan mevcut string literal çağrıları derlemeye devam eder.

- try await Adapty.updateAttribution(attribution, source: "adjust")
+ try await Adapty.updateAttribution(attribution, source: .adjust)

Önceden tanımlanmış kaynaklar: .appleAds, .adjust, .appsflyer, .branch, .tenjin. Kaynağı bir String değişkeninde tutuyorsanız şu şekilde sarmalayın: AdaptyAttributionSource(rawValue: yourSource).

setIntegrationIdentifier(_:)

setIntegrationIdentifier(key:value:), bir veya daha fazla AdaptyIntegrationIdentifier değeri alan değişken sayıda parametre kabul eden bir metotla değiştirildi. Ham string anahtarlar yerine önceden tanımlanmış fabrika metotlarını kullanın:

- try await Adapty.setIntegrationIdentifier(key: "appsflyer_id", value: uid)
+ try await Adapty.setIntegrationIdentifier(.appsflyerId(uid))

Tek bir çağrıda birden fazla tanımlayıcı ayarlayabilirsiniz:

try await Adapty.setIntegrationIdentifier(
    .appsflyerId(uid),
    .adjustDeviceId(adid)
)

Her eski anahtar dizesini fabrika metoduyla değiştirin:

v3 anahtarıv4 factory
"adjust_device_id".adjustDeviceId(_:)
"airbridge_device_id".airbridgeDeviceId(_:)
"amplitude_user_id".amplitudeUserId(_:)
"amplitude_device_id".amplitudeDeviceId(_:)
"appmetrica_device_id".appmetricaDeviceId(_:)
"appmetrica_profile_id".appmetricaProfileId(_:)
"appsflyer_id".appsflyerId(_:)
"branch_id".branchId(_:)
"facebook_anonymous_id".facebookAnonymousId(_:)
"firebase_app_instance_id".firebaseAppInstanceId(_:)
"mixpanel_user_id".mixpanelUserId(_:)
"one_signal_subscription_id".oneSignalSubscriptionId(_:)
"one_signal_player_id".oneSignalPlayerId(_:)
"posthog_distinct_user_id".posthogDistinctUserId(_:)
"pushwoosh_hwid".pushwooshHWID(_:)
"tenjin_analytics_installation_id".tenjinAnalyticsInstallationId(_:)