Flow ve paywall olaylarını yönetme - iOS

Bu kılavuz; satın almalar, geri yüklemeler, ürün seçimi ve paywall görüntüleme için olay yönetimini kapsar. Bunların yanı sıra buton işlemlerini de (paywall kapatma, bağlantı açma vb.) uygulamanız gerekir. Ayrıntılar için buton eylemlerini yönetme kılavuzumuza bakın.

Flow’lar ve paywalllar, satın alma yapmak ve geri yüklemek için ekstra kod gerektirmez. Ancak uygulamanızın yanıt verebileceği bazı olaylar üretirler. Bu olaylar arasında düğme basışları (kapat düğmeleri, URL’ler, ürün seçimleri vb.) ve satın alma ile ilgili eylemler hakkında bildirimler bulunur. Bu olaylara nasıl yanıt vereceğinizi aşağıda öğrenin.

Adapty SDK’nın bir mobil uygulamaya nasıl entegre edildiğine dair gerçek dünya örneği görmek ister misiniz? Paywall görüntüleme, satın alma yapma ve diğer temel işlevler dahil olmak üzere tam kurulumu sergileyen örnek uygulamalarımıza göz atın.

SwiftUI’da olayları yönetme

Mobil uygulamanızdaki flow veya paywall ekranında gerçekleşen süreçleri kontrol etmek ya da izlemek için SwiftUI’da .flow modifier’ını kullanın:

@State var flowPresented = false

var body: some View {
    Text("Hello, AdaptyUI!")
        .flow(
            isPresented: $flowPresented,
            flowConfiguration: flowConfiguration,
            didPerformAction: { action in
                switch action {
                    case .close:
                        flowPresented = false
                    case let .openURL(url):
                        // handle opening the URL (incl. for terms and privacy)
                    default:
                        // handle other actions
                }
            },
            didSelectProduct: { product in /* Handle the event */ },
            didStartPurchase: { product in /* Handle the event */ },
            didFinishPurchase: { product, purchaseResult in /* dismiss, or do nothing to let the flow continue */ },
            didFailPurchase: { product, error in /* handle the error */ },
            didStartRestore: { /* Handle the event */ },
            didFinishRestore: { profile in /* check access level and dismiss */ },
            didFailRestore: { error in /* handle the error */ },
            didReceiveError: { error in
                flowPresented = false
            },
            didFailLoadingProducts: { error in
                // Return `true` to retry loading
                return false
            }
        )
}

Yalnızca ihtiyacınız olan closure parametrelerini kaydedebilir, ihtiyaç duymadıklarınızı atlayabilirsiniz.

ParametreZorunluAçıklama
isPresentedzorunluFlow veya paywall ekranının görüntülenip görüntülenmeyeceğini yöneten bir binding.
flowConfigurationzorunluFlow veya paywallın görsel ayrıntılarını içeren bir AdaptyUI.FlowConfiguration nesnesi. Daha fazla bilgi için Flow ve paywall’ları al bölümüne bakın.
didFinishPurchasezorunluAdapty.makePurchase() başarıyla tamamlandığında çağrılır. Flow otomatik olarak kapanmaz — burada presentation binding’inizi false olarak ayarlayın ya da flow’un satın alma sonrasında devam etmesi için hiçbir şey yapmayın.
didFailPurchasezorunluAdapty.makePurchase() başarısız olduğunda çağrılır.
didFinishRestorezorunluAdapty.restorePurchases() başarıyla tamamlandığında çağrılır.
didFailRestorezorunluAdapty.restorePurchases() başarısız olduğunda çağrılır.
didReceiveErrorzorunluFlow bir render hatası veya flow betiğinden kaynaklanan bir çalışma zamanı hatasıyla karşılaştığında çağrılır (örneğin, bir JavaScript istisnası, AdaptyUIError kodu 4105). Render hatası durumunda Adapty Destek ile iletişime geçin.
placeholderBuilderisteğe bağlıFlow veya paywall yüklenirken yer tutucu görünümü oluşturmak için kullanılan bir fonksiyon. Varsayılan olarak ProgressView kullanılır.
fullScreenisteğe bağlıFlow veya paywallın tam ekran modunda mı yoksa bir sheet olarak mı görüneceğini belirler. Varsayılan değer true’dur.
didAppearisteğe bağlıFlow veya paywall görünümü ekranda göründüğünde çağrılır.
didDisappearisteğe bağlıFlow veya paywall görünümü kapatıldığında çağrılır.
didPerformActionisteğe bağlıKullanıcı bir butona tıkladığında çağrılır. İki eylem kimliği önceden tanımlıdır: close ve openURL; diğerleri özeldir ve builder’da ayarlanabilir.
didSelectProductisteğe bağlıKullanıcı veya sistem tarafından satın alma için bir ürün seçildiğinde çağrılır.
didStartPurchaseisteğe bağlıKullanıcı satın alma sürecini başlattığında çağrılır.
didFinishWebPaymentNavigationisteğe bağlıWeb ödeme navigasyonu tamamlandığında çağrılır.
didStartRestoreisteğe bağlıKullanıcı geri yükleme sürecini başlattığında çağrılır.
didFailLoadingProductsisteğe bağlıÜrün yükleme sırasında hatalar oluştuğunda çağrılır. Yüklemeyi yeniden denemek için true döndürün.
didPartiallyLoadProductsisteğe bağlıÜrünler kısmen yüklendiğinde çağrılır.
showAlertItemisteğe bağlıFlow veya paywallın üzerinde uyarı öğelerinin görüntülenmesini yöneten bir binding.
showAlertBuilderisteğe bağlıUyarı görünümünü oluşturmak için kullanılan bir fonksiyon.

UIKit’te olayları yönetme

UIKit uygulamalarında olaylar, AdaptyFlowControllerDelegate protokolü aracılığıyla yönetilir. AdaptyFlowController’ı AdaptyFlowControllerDelegate ile nasıl kuracağınızı öğrenmek için Flow ve paywallları gösterme - iOS sayfasına bakın. Protokol 13 metot tanımlar. Bunların dördünün varsayılan uygulaması yoktur ve uyum sağlarken mutlaka uygulanması gerekir: didFinishPurchase, didFailPurchase, didFinishRestoreWith ve didFailRestoreWith. Geri kalanlar varsayılan olarak işlemsiz (no-op) uygulamalarla gelir ve özel davranış istediğinizde bunları geçersiz kılabilirsiniz. Metotlar aşağıda amaca göre gruplandırılmıştır.

Yaşam Döngüsü

func flowControllerDidAppear(_ controller: AdaptyFlowController) { }

func flowControllerDidDisappear(_ controller: AdaptyFlowController) { }

Bu metodlar, flow veya paywall görünümü gösterildiğinde ya da kapatıldığında tetiklenir.

Kullanıcı eylemleri

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

AdaptyUI.Action durumları:

  • .close — varsayılan davranış, controller’ı kapatır. Controller’ı ekranda tutmak veya ekstra temizlik işlemleri yapmak için bu davranışı override edebilirsiniz.
  • .openURL(url:) — varsayılan davranış, URL’yi UIApplication.shared.open(...) ile açar.
  • .custom(id:) — builder’da özel bir eylem ID’si atanmış butonlar için tetiklenir.

Ürün seçimi

func flowController(
    _ controller: AdaptyFlowController,
    didSelectProduct product: AdaptyPaywallProduct
) { }

Kullanıcı veya sistem tarafından satın alma için bir ürün seçildiğinde çağrılır. Ürün, tam teklif bilgisini taşır (v4’te uygunluk otomatik olarak belirlenir — ayrı bir AdaptyPaywallProductWithoutDeterminingOffer türü yoktur).

Satın alma etkinlikleri

func flowController(
    _ controller: AdaptyFlowController,
    didStartPurchase product: AdaptyPaywallProduct
) { }

func flowController(
    _ controller: AdaptyFlowController,
    didFinishPurchase product: AdaptyPaywallProduct,
    purchaseResult: AdaptyPurchaseResult
) {
    if !purchaseResult.isPurchaseCancelled {
        controller.dismiss(animated: true) // or do nothing to let the flow continue
    }
}

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

didFinishPurchase ve didFailPurchase için varsayılan bir uygulama yoktur ve bunların implemente edilmesi zorunludur. Controller, başarılı bir satın alma işleminin ardından kendini kapatmaz — uygun olduğunda controller.dismiss(animated:) çağırın ya da çok ekranlı bir flow devam etsin istiyorsanız hiçbir şey yapmayın.

Geri yükleme olayları

func flowControllerDidStartRestore(_ controller: AdaptyFlowController) { }

func flowController(
    _ controller: AdaptyFlowController,
    didFinishRestoreWith profile: AdaptyProfile
) { }

func flowController(
    _ controller: AdaptyFlowController,
    didFailRestoreWith error: AdaptyError
) { }

didFinishRestoreWith ve didFailRestoreWith için varsayılan bir uygulama bulunmaz. Controller’ı kapatmadan önce döndürülen AdaptyProfile’ın istediğiniz access level’ı içerip içermediğini kontrol edin.

Flow hataları ve ürün yükleme hataları

func flowController(
    _ controller: AdaptyFlowController,
    didReceiveError error: AdaptyUIError
) { }

func flowController(
    _ controller: AdaptyFlowController,
    didFailLoadingProductsWith error: AdaptyError
) -> Bool {
    // Return `true` to retry product loading; default returns `false`.
    return false
}

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

didReceiveError, render hataları ve flow script’inden gelen çalışma zamanı hataları için tetiklenir (JavaScript istisnaları, AdaptyUIError kodu 4105). Render hataları için Adapty Destek ile iletişime geçin. Yükleme hataları için geçici ağ sorunlarında yeniden denemek amacıyla didFailLoadingProductsWith fonksiyonundan true döndürün.

Web ödeme navigasyonu

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

Web ödeme navigasyonu tamamlandıktan sonra çağrılır; başarılı veya başarısız olup olmadığına bakılmaksızın.

Bu kılavuz, satın almalar, yenileme işlemleri, ürün seçimi ve paywall oluşturma için event yönetimini kapsamaktadır. Ayrıca buton işlemlerini de (paywallı kapatma, bağlantı açma vb.) uygulamanız gerekir. Ayrıntılar için buton eylemlerini yönetme kılavuzumuza bakın.

Paywall Builder ile yapılandırılmış paywalllar, satın alma yapmak ve geri yüklemek için ekstra kod gerektirmez. Ancak uygulamanızın yanıt verebileceği bazı olaylar üretirler. Bu olaylar; düğme basışlarını (kapat düğmeleri, URL’ler, ürün seçimleri vb.) ve paywall üzerinde gerçekleştirilen satın alma ile ilgili işlemlere dair bildirimleri kapsar. Bu olaylara nasıl yanıt vereceğinizi aşağıda öğrenebilirsiniz.

Bu kılavuz yalnızca Adapty SDK v3.0 veya sonrasını gerektiren yeni Paywall Builder paywallları içindir.

Adapty SDK’nın bir mobil uygulamaya nasıl entegre edildiğini gerçek dünyadan bir örnekle görmek ister misiniz? Tam kurulumu, paywall gösterimi, satın alma yapma ve diğer temel işlevleri içeren örnek uygulamalarımıza göz atın.

SwiftUI’da olayları yönetme

Mobil uygulamanızdaki paywall ekranında gerçekleşen süreçleri kontrol etmek veya izlemek için SwiftUI’da .paywall modifierını kullanın:

@State var paywallPresented = false

var body: some View {
	Text("Hello, AdaptyUI!")
			.paywall(
          isPresented: $paywallPresented,
          paywall: paywall,
          viewConfiguration: viewConfig,
          didPerformAction: { action in
              switch action {
                  case .close:
                      paywallPresented = false
                  case let .openURL(url):
                      // URL açmayı yönet (şartlar ve gizlilik dahil)
                  default:
                      // diğer eylemleri yönet
              }
          },
          didSelectProduct: { /* Olayı yönet */  },
          didStartPurchase: { /* Olayı yönet */ },
          didFinishPurchase: { product, info in /* Olayı yönet */ },
          didFailPurchase: { product, error in /* Olayı yönet */ },
          didStartRestore: { /* Olayı yönet */ },
          didFinishRestore: { /* Olayı yönet */ },
          didFailRestore: { /* Olayı yönet */ },
          didFailRendering: { error in
              paywallPresented = false
          },
          didFailLoadingProducts: { error in
              return false
          }
      )
}

Yalnızca ihtiyacınız olan closure parametrelerini kaydedebilir, ihtiyaç duymadıklarınızı atlayabilirsiniz. Bu durumda kullanılmayan closure parametreleri oluşturulmaz.

ParametreZorunluAçıklama
isPresentedzorunluPaywall ekranının görüntülenip görüntülenmediğini yöneten bir bağlayıcı.
paywallConfigurationzorunluPaywallın görsel ayrıntılarını içeren bir AdaptyUI.PaywallConfiguration nesnesi. AdaptyUI.paywallConfiguration(for:products:viewConfiguration:observerModeResolver:tagResolver:timerResolver:) metodunu kullanın. Daha fazla ayrıntı için Paywall Builder paywalllarını ve yapılandırmalarını getirme konusuna bakın.
didFailPurchasezorunluBir satın alma işlemi hatalar nedeniyle başarısız olduğunda çağrılır (örn. ödemeye izin verilmemesi, ağ sorunları, geçersiz ürün). Kullanıcı iptalleri veya bekleyen ödemeler için çağrılmaz.
didFinishRestorezorunluSatın alma işlemi başarıyla tamamlandığında çağrılır.
didFailRestorezorunluBir satın alma işlemi geri yüklenirken hata oluştuğunda çağrılır.
didFailRenderingzorunluArayüz oluşturulurken hata oluşursa çağrılır. Bu durumda Adapty Destek ekibiyle iletişime geçin.
fullScreenisteğe bağlıPaywallın tam ekran modunda mı yoksa modal olarak mı görüneceğini belirler. Varsayılan değer true.
didAppearisteğe bağlıPaywall görünümü ekranda belirdiğinde çağrılır. Ayrıca kullanıcı paywall içindeki web paywall düğmesine tıkladığında ve bir web paywall uygulama içi tarayıcıda açıldığında da çağrılır.
didDisappearisteğe bağlıPaywall görünümü kapatıldığında çağrılır. Ayrıca paywall’dan açılan bir web paywall uygulama içi tarayıcıda ekrandan kaybolduğunda da çağrılır.
didPerformActionisteğe bağlıKullanıcı bir düğmeye tıkladığında çağrılır. Farklı düğmelerin farklı eylem kimlikleri vardır. close ve openURL olmak üzere iki eylem kimliği önceden tanımlanmıştır; diğerleri özeldir ve builder’da ayarlanabilir.
didSelectProductisteğe bağlıBir ürün satın almak için seçildiğinde (kullanıcı veya sistem tarafından) bu callback çağrılır.
didStartPurchaseisteğe bağlıKullanıcı satın alma sürecini başlattığında çağrılır.
didFinishPurchaseisteğe bağlıSatın alma işlemi başarıyla tamamlandığında çağrılır.
didFinishWebPaymentNavigationisteğe bağlıSatın alma için bir web paywall açılmaya çalışıldıktan sonra, başarılı olsun ya da olmasın, çağrılır.
didStartRestoreisteğe bağlıKullanıcı geri yükleme sürecini başlattığında çağrılır.
didFailLoadingProductsisteğe bağlıÜrün yükleme sırasında hatalar oluştuğunda çağrılır. Yüklemeyi yeniden denemek için true döndürün.
didPartiallyLoadProductsisteğe bağlıÜrünler kısmen yüklendiğinde çağrılır.
showAlertItemisteğe bağlıPaywall’ın üzerinde uyarı öğelerinin görüntülenmesini yöneten bir bağlayıcı.
showAlertBuilderisteğe bağlıUyarı görünümünü oluşturmaya yarayan bir fonksiyon.
placeholderBuilderisteğe bağlıPaywall yüklenirken yer tutucu görünümü oluşturmaya yarayan bir fonksiyon.

UIKit’te olayları yönetme

Mobil uygulamanızdaki paywall ekranında gerçekleşen süreçleri kontrol etmek veya izlemek için AdaptyPaywallControllerDelegate metodlarını uygulayın.

Kullanıcı kaynaklı olaylar

Ürün seçimi

Bir kullanıcı satın alma için bir ürün seçerse bu metod çağrılır:

    func paywallController(
        _ controller: AdaptyPaywallController,
        didSelectProduct product: AdaptyPaywallProductWithoutDeterminingOffer
    ) { }
Olay örneği (Genişletmek için tıklayın)
{
  "product": {
    "vendorProductId": "premium_monthly",
    "localizedTitle": "Premium Monthly",
    "localizedDescription": "Premium subscription for 1 month",
    "localizedPrice": "$9.99",
    "price": 9.99,
    "currencyCode": "USD"
  }
}

Satın alma başlatıldı

Bir kullanıcı satın alma sürecini başlatırsa bu metod çağrılır:

func paywallController(_ controller: AdaptyPaywallController,
                       didStartPurchase product: AdaptyPaywallProduct) {
}
Olay örneği (Genişletmek için tıklayın)
{
  "product": {
    "vendorProductId": "premium_monthly",
    "localizedTitle": "Premium Monthly",
    "localizedDescription": "Premium subscription for 1 month",
    "localizedPrice": "$9.99",
    "price": 9.99,
    "currencyCode": "USD"
  }
}

Observer modunda çağrılmaz. Ayrıntılar için iOS - Observer modunda Paywall Builder paywalllarını gösterme konusuna bakın.

Web paywall kullanarak satın alma başlatıldı

Bir kullanıcı web paywall kullanarak satın alma sürecini başlatırsa bu metod çağrılır:

func paywallController(
        _ controller: AdaptyPaywallController,
        shouldContinueWebPaymentNavigation product: AdaptyPaywallProduct
    ) {
    }
Olay örneği (Genişletmek için tıklayın)
{
  "product": {
    "vendorProductId": "premium_monthly",
    "localizedTitle": "Premium Monthly",
    "localizedDescription": "Premium subscription for 1 month",
    "localizedPrice": "$9.99",
    "price": 9.99,
    "currencyCode": "USD"
  }
}

Başarılı veya iptal edilen satın alma

Satın alma başarılı olursa bu metod çağrılır:

func paywallController(
    _ controller: AdaptyPaywallController,
    didFinishPurchase product: AdaptyPaywallProductWithoutDeterminingOffer,
    purchaseResult: AdaptyPurchaseResult
) { }
}
Olay örnekleri (Genişletmek için tıklayın)
// Successful purchase
{
  "product": {
    "vendorProductId": "premium_monthly",
    "localizedTitle": "Premium Monthly",
    "localizedDescription": "Premium subscription for 1 month",
    "localizedPrice": "$9.99",
    "price": 9.99,
    "currencyCode": "USD"
  },
  "purchaseResult": {
    "type": "success",
    "profile": {
      "accessLevels": {
        "premium": {
          "id": "premium",
          "isActive": true,
          "expiresAt": "2024-02-15T10:30:00Z"
        }
      }
    }
  }
}

// Cancelled purchase
{
  "product": {
    "vendorProductId": "premium_monthly",
    "localizedTitle": "Premium Monthly",
    "localizedDescription": "Premium subscription for 1 month",
    "localizedPrice": "$9.99",
    "price": 9.99,
    "currencyCode": "USD"
  },
  "purchaseResult": {
    "type": "cancelled"
  }
}

Bu durumda paywall ekranını kapatmanızı öneririz.

Observer modunda çağrılmaz. Ayrıntılar için iOS - Observer modunda Paywall Builder paywalllarını gösterme konusuna bakın.

Başarısız satın alma

Bir satın alma hata nedeniyle başarısız olursa bu metod çağrılır. Bu; StoreKit hatalarını (ödeme kısıtlamaları, geçersiz ürünler, ağ hataları), işlem doğrulama hatalarını ve sistem hatalarını kapsar. Kullanıcı iptalleri, iptal edilmiş sonuçla birlikte didFinishPurchase metodunu tetikler; bekleyen ödemeler ise bu metodu tetiklemez.

func paywallController(
    _ controller: AdaptyPaywallController,
    didFailPurchase product: AdaptyPaywallProduct,
    error: AdaptyError
) { }
Olay örneği (Genişletmek için tıklayın)
{
  "product": {
    "vendorProductId": "premium_monthly",
    "localizedTitle": "Premium Monthly",
    "localizedDescription": "Premium subscription for 1 month",
    "localizedPrice": "$9.99",
    "price": 9.99,
    "currencyCode": "USD"
  },
  "error": {
    "code": "purchase_failed",
    "message": "Purchase failed due to insufficient funds",
    "details": {
      "underlyingError": "Insufficient funds in account"
    }
  }
}

Observer modunda çağrılmaz. Ayrıntılar için iOS - Observer modunda Paywall Builder paywalllarını gösterme konusuna bakın.

Web paywall kullanarak başarısız satın alma

Adapty.openWebPaywall() başarısız olursa bu metod çağrılır:

func paywallController(
        _ controller: AdaptyPaywallController,
        didFailWebPaymentNavigation product: AdaptyPaywallProduct,
        error: AdaptyError
    ) { }
Olay örneği (Genişletmek için tıklayın)
{
  "product": {
    "vendorProductId": "premium_monthly",
    "localizedTitle": "Premium Monthly",
    "localizedDescription": "Premium subscription for 1 month",
    "localizedPrice": "$9.99",
    "price": 9.99,
    "currencyCode": "USD"
  },
  "error": {
    "code": "web_payment_failed",
    "message": "Web payment navigation failed",
    "details": {
      "underlyingError": "Network connection error"
    }
  }
}

Başarılı geri yükleme

Satın alma geri yükleme başarılı olursa bu metod çağrılır:

func paywallController(
    _ controller: AdaptyPaywallController, 
    didFinishRestoreWith profile: AdaptyProfile
) { }
Olay örneği (Genişletmek için tıklayın)
{
  "profile": {
    "accessLevels": {
      "premium": {
        "id": "premium",
        "isActive": true,
        "expiresAt": "2024-02-15T10:30:00Z"
      }
    },
    "subscriptions": [
      {
        "vendorProductId": "premium_monthly",
        "isActive": true,
        "expiresAt": "2024-02-15T10:30:00Z"
      }
    ]
  }
}

Kullanıcının gerekli accessLevel’a sahip olması durumunda ekranı kapatmanızı öneririz. Nasıl kontrol edileceğini öğrenmek için Abonelik durumu konusuna bakın.

Başarısız geri yükleme

Satın alma geri yükleme başarısız olursa bu metod çağrılır:

public func paywallController(
    _ controller: AdaptyPaywallController, 
    didFailRestoreWith error: AdaptyError
) { }
Olay örneği (Genişletmek için tıklayın)
{
  "error": {
    "code": "restore_failed",
    "message": "Purchase restoration failed",
    "details": {
      "underlyingError": "No previous purchases found"
    }
  }
}

Veri getirme ve oluşturma

Ürün yükleme hataları

Başlatma sırasında ürün dizisini geçmezseniz AdaptyUI gerekli nesneleri sunucudan kendisi alır. Bu işlem başarısız olursa AdaptyUI hatayı bu metodu çağırarak bildirir:

public func paywallController(
    _ controller: AdaptyPaywallController,
    didFailLoadingProductsWith error: AdaptyError
) -> Bool {
    return true
}
Olay örneği (Genişletmek için tıklayın)
{
  "error": {
    "code": "products_loading_failed",
    "message": "Failed to load products from the server",
    "details": {
      "underlyingError": "Network timeout"
    }
  }
}

true döndürürseniz AdaptyUI isteği 2 saniye sonra tekrarlar.

Oluşturma hataları

Arayüz oluşturulurken bir hata meydana gelirse bu metod tarafından bildirilir:

public func paywallController(
    _ controller: AdaptyPaywallController,
    didFailRenderingWith error: AdaptyError
) { }
Olay örneği (Genişletmek için tıklayın)
{
  "error": {
    "code": "rendering_failed",
    "message": "Failed to render paywall interface",
    "details": {
      "underlyingError": "Invalid paywall configuration"
    }
  }
}

Normal bir durumda bu tür hatalar oluşmamalıdır; eğer böyle bir hatayla karşılaşırsanız lütfen bize bildirin.