Flow ve paywallları görüntüleme - React Native

Flow ve paywall görüntüleme
Flow'lar Flow & Paywall Builder ile oluşturulur — cihazda natif olarak render edilir, WebView gerekmez
Eski Paywall Builder paywall'ları Eski Paywall Builder ile oluşturulmuş tüm içerik

Bir flow ya da eski Paywall Builder’da bir paywall oluşturduysanız, kullanıcıya göstermek için onu mobil uygulama kodunuzda render etmeniz gerekmez. Böyle bir flow, içinde ne gösterileceğini ve nasıl gösterileceğini zaten kapsar.

Başlamadan önce şunları yaptığınızdan emin olun:

  1. Bir flow veya bir paywall oluşturdunuz.
  2. Onu bir placement’a eklediniz.
  3. Flow’u getirdiniz ve view’ı hazırladınız.
Warning

Bu kılavuz yalnızca Adapty tarafından render edilen flow’lar ve paywall’lar içindir; SDK v4.0 veya üzeri gerektirir. Flow’ların sunulma süreci, remote config paywall’larında farklılık gösterir.

Adapty React Native SDK, flow’ları ve paywall’ları sunmak için iki yol sunar:

  • React bileşeni: Gömülü bileşen, uygulamanızın mimarisine ve navigasyon sistemine entegre etmenizi sağlar.

  • Modal sunum

React bileşeni

Bir flow’u mevcut bileşen ağacınıza gömmek için, AdaptyFlowView bileşenini doğrudan React Native bileşen hiyerarşinizde kullanın. Gömülü bileşen, onu uygulamanızın mimarisine ve navigasyon sistemine entegre etmenize olanak tanır.

Tip

AdaptyFlowView bileşeni, view’ini render edildiğinde oluşturur; yani yapılandırma ve görseller yüklendiğinde. Bunları önceden yüklemek için, uygulamanızda daha erken bir noktada aynı flow için createFlowView çağırın. Bileşen daha sonra önbelleğe alınmış verileri yeniden kullanır ve indirmeleri beklemeden render eder.


function MyFlow({ flow }) {
  const flowParams = useMemo(() => ({
    loadTimeoutMs: 3000,
    locale: 'en', // The localization to render the flow with
  }), []);

  const onCloseButtonPress = useCallback<FlowEventHandlers['onCloseButtonPress']>(() => {}, []);
  const onProductSelected = useCallback<FlowEventHandlers['onProductSelected']>((productId) => {}, []);
  const onPurchaseStarted = useCallback<FlowEventHandlers['onPurchaseStarted']>((product) => {}, []);
  const onPurchaseCompleted = useCallback<FlowEventHandlers['onPurchaseCompleted']>((purchaseResult, product) => {}, []);
  const onPurchaseFailed = useCallback<FlowEventHandlers['onPurchaseFailed']>((error, product) => {}, []);
  const onRestoreStarted = useCallback<FlowEventHandlers['onRestoreStarted']>(() => {}, []);
  const onRestoreCompleted = useCallback<FlowEventHandlers['onRestoreCompleted']>((profile) => {}, []);
  const onRestoreFailed = useCallback<FlowEventHandlers['onRestoreFailed']>((error) => {}, []);
  const onAppeared = useCallback<FlowEventHandlers['onAppeared']>((view) => {}, []);
  const onError = useCallback<FlowEventHandlers['onError']>((error) => {}, []);
  const onLoadingProductsFailed = useCallback<FlowEventHandlers['onLoadingProductsFailed']>((error) => {}, []);
  const onUrlPress = useCallback<FlowEventHandlers['onUrlPress']>((url) => {}, []);
  const onCustomAction = useCallback<FlowEventHandlers['onCustomAction']>((actionId) => {}, []);
  const onWebPaymentNavigationFinished = useCallback<FlowEventHandlers['onWebPaymentNavigationFinished']>(() => {}, []);

  return (
    <AdaptyFlowView
      flow={flow}
      params={flowParams}
      style={styles.flow}
      onCloseButtonPress={onCloseButtonPress}
      onProductSelected={onProductSelected}
      onPurchaseStarted={onPurchaseStarted}
      onPurchaseCompleted={onPurchaseCompleted}
      onPurchaseFailed={onPurchaseFailed}
      onRestoreStarted={onRestoreStarted}
      onRestoreCompleted={onRestoreCompleted}
      onRestoreFailed={onRestoreFailed}
      onAppeared={onAppeared}
      onError={onError}
      onLoadingProductsFailed={onLoadingProductsFailed}
      onCustomAction={onCustomAction}
      onUrlPress={onUrlPress}
      onWebPaymentNavigationFinished={onWebPaymentNavigationFinished}
    />
  );
}

Bir flow’u bağımsız bir ekran olarak görüntülemek için, createFlowView metoduyla oluşturulan view üzerinde view.present() metodunu kullanın. Her view yalnızca bir kez kullanılabilir. Flow’u tekrar görüntülemeniz gerekirse, yeni bir view örneği oluşturmak için createFlowView’u bir kez daha çağırın.

Warning

Aynı view’i yeniden oluşturmadan tekrar kullanmak yasaktır. Bu, bir AdaptyUIError.viewAlreadyPresented hatasıyla sonuçlanır.


const view = await createFlowView(flow);

// Optional: handle flow events (close, purchase, restore, etc)
// view.setEventHandlers({ ... });

try {
  await view.present();
} catch (error) {
  // handle the error
}
Important

setEventHandlers’ı birden çok kez çağırmak, sağladığınız işleyicileri geçersiz kılar; söz konusu belirli olaylar için hem varsayılan hem de önceden ayarlanmış işleyicilerin yerini alır.

iOS sunum stilini yapılandırın

Flow’un iOS’ta nasıl sunulacağını, present() metoduna iosPresentationStyle parametresini ileterek yapılandırın. Parametre 'full_screen' (varsayılan) veya 'page_sheet' değerlerini kabul eder.

try {
  await view.present({ iosPresentationStyle: 'page_sheet' });
} catch (error) {
  // handle the error
}

Geliştirici tanımlı zamanlayıcı kullanımı

Mobil uygulamanızda geliştirici tanımlı zamanlayıcılar kullanmak için, bu örnekte CUSTOM_TIMER_NY olan timerId’yi kullanın; bu, Adapty kontrol panelinde ayarladığınız geliştirici tanımlı zamanlayıcının Timer ID’sidir. Bu sayede uygulamanız zamanlayıcıyı doğru değerle dinamik olarak günceller; örneğin 13g 09s 03d 34s (zamanlayıcının bitiş zamanı olan Yılbaşı’ndan mevcut zamanın çıkarılmasıyla hesaplanır).

Bu örnekte CUSTOM_TIMER_NY, Adapty kontrol panelinde ayarladığınız geliştirici tanımlı zamanlayıcının Timer ID’sidir. timerResolver, uygulamanızın zamanlayıcıyı doğru değerle dinamik olarak güncellemesini sağlar; örneğin 13g 09s 03d 34s (zamanlayıcının bitiş zamanı olan Yılbaşı’ndan mevcut zamanın çıkarılmasıyla hesaplanır).

Diyalog gösterme

Android’de bir flow view sunulduğunda, yerel uyarı diyalogları yerine bu metodu kullanın. Android’de normal RN uyarıları flow view’in arkasında görünür, bu da onları kullanıcılara görünmez kılar. Bu metot, tüm platformlarda diyalogun flow’un üzerinde düzgün şekilde sunulmasını sağlar.

try {
  const action = await view.showDialog({
    title: 'Close paywall?',
    content: 'You will lose access to exclusive offers.',
    primaryActionTitle: 'Stay',
    secondaryActionTitle: 'Close',
  });

  if (action === 'secondary') {
    // User confirmed - close the flow
    await view.dismiss();
  }
  // If primary - do nothing, user stays
} catch (error) {
  // handle error
}

Bir aboneliği başka biriyle değiştirme

Android’de başka bir abonelik etkinken bir kullanıcı yeni bir abonelik satın almaya çalıştığında, flow view’i oluştururken abonelik güncelleme parametrelerini geçirerek yeni satın almanın nasıl yönetileceğini kontrol edebilirsiniz. Mevcut aboneliği yenisiyle değiştirmek için, createFlowView içinde oldSubVendorProductId ve prorationMode parametreleriyle birlikte productPurchaseParams kullanın.


const productPurchaseParams = flow.paywalls
  .flatMap((variation) => variation.productIdentifiers)
  .map((productId) => {
    let params = {};
    if (Platform.OS === 'android') {
      params.android = {
        subscriptionUpdateParams: {
          oldSubVendorProductId: 'PRODUCT_ID_OF_THE_CURRENT_ACTIVE_SUBSCRIPTION',
          prorationMode: 'with_time_proration',
        },
      };
    }
    return { productId, params };
  });

const view = await createFlowView(flow, { productPurchaseParams });

Paywall Builder kullanarak bir paywall özelleştirdiyseniz, onu kullanıcıya göstermek için mobil uygulama kodunuzda render etme derdine girmenize gerek yoktur. Böyle bir paywall, hem paywall içinde ne gösterileceğini hem de nasıl gösterileceğini içerir.

Başlamadan önce şunlardan emin olun:

  1. Bir paywall oluşturdunuz.
  2. Paywall’ı bir placement’a eklediniz.
  3. Paywall’ı getirdiniz ve view’i hazırladınız.
Warning

Bu kılavuz yalnızca Adapty SDK 3.x için eski Paywall Builder’da oluşturulmuş paywallları kapsar. SDK v3.0 veya üzeri gerektirir. SDK 2.x veya öncesi için oluşturulmuş bir paywall ya da remote config paywall sunmak farklı şekilde çalışır.

Adapty React Native SDK, paywallları sunmak için iki yöntem sunar:

  • React bileşeni: Gömülü bileşen, uygulamanızın mimarisine ve navigasyon sistemine entegre etmenizi sağlar.

  • Modal sunum

React bileşeni

Note

React bileşeni yaklaşımı SDK 3.14.0 veya üstünü gerektirir.

Bir paywallı mevcut bileşen ağacınıza gömmek için AdaptyPaywallView bileşenini doğrudan React Native bileşen hiyerarşinizde kullanın. Gömülü bileşen, uygulamanızın mimarisine ve navigasyon sistemine entegre etmenize olanak tanır.

Note

Android’de, paywall durum çubuğunun arkasına uzanmıyorsa üst kısmında görsel bir katman belirebiilir. Paywalllarınız için bunu kapatmanızı öneririz. Bkz. Paywallın üst kısmındaki görsel katman (Android).


function MyPaywall({ paywall }) {
  const paywallParams = useMemo(() => ({
    loadTimeoutMs: 3000,
  }), []);

  const onCloseButtonPress = useCallback<EventHandlers['onCloseButtonPress']>(() => {}, []);
  const onProductSelected = useCallback<EventHandlers['onProductSelected']>((productId) => {}, []);
  const onPurchaseStarted = useCallback<EventHandlers['onPurchaseStarted']>((product) => {}, []);
  const onPurchaseCompleted = useCallback<EventHandlers['onPurchaseCompleted']>((purchaseResult, product) => {}, []);
  const onPurchaseFailed = useCallback<EventHandlers['onPurchaseFailed']>((error, product) => {}, []);
  const onRestoreStarted = useCallback<EventHandlers['onRestoreStarted']>(() => {}, []);
  const onRestoreCompleted = useCallback<EventHandlers['onRestoreCompleted']>((profile) => {}, []);
  const onRestoreFailed = useCallback<EventHandlers['onRestoreFailed']>((error) => {}, []);
  const onPaywallShown = useCallback<EventHandlers['onPaywallShown']>(() => {}, []);
  const onRenderingFailed = useCallback<EventHandlers['onRenderingFailed']>((error) => {}, []);
  const onLoadingProductsFailed = useCallback<EventHandlers['onLoadingProductsFailed']>((error) => {}, []);
  const onUrlPress = useCallback<EventHandlers['onUrlPress']>((url) => {}, []);
  const onCustomAction = useCallback<EventHandlers['onCustomAction']>((actionId) => {}, []);
  const onWebPaymentNavigationFinished = useCallback<EventHandlers['onWebPaymentNavigationFinished']>(() => {}, []);

  return (
    <AdaptyPaywallView
      paywall={paywall}
      params={paywallParams}
      style={styles.paywall}
      onCloseButtonPress={onCloseButtonPress}
      onProductSelected={onProductSelected}
      onPurchaseStarted={onPurchaseStarted}
      onPurchaseCompleted={onPurchaseCompleted}
      onPurchaseFailed={onPurchaseFailed}
      onRestoreStarted={onRestoreStarted}
      onRestoreCompleted={onRestoreCompleted}
      onRestoreFailed={onRestoreFailed}
      onPaywallShown={onPaywallShown}
      onRenderingFailed={onRenderingFailed}
      onLoadingProductsFailed={onLoadingProductsFailed}
      onCustomAction={onCustomAction}
      onUrlPress={onUrlPress}
      onWebPaymentNavigationFinished={onWebPaymentNavigationFinished}
    />
  );
}

Bir paywallı bağımsız bir ekran olarak göstermek için, createPaywallView metoduyla oluşturulan view üzerinde view.present() metodunu kullanın. Her view yalnızca bir kez kullanılabilir. Paywallı tekrar göstermeniz gerekiyorsa yeni bir view örneği oluşturmak için createPaywallView’i bir kez daha çağırın.

Warning

Aynı view’ı yeniden oluşturmadan tekrar kullanmak yasaktır. Bu durum AdaptyUIError.viewAlreadyPresented hatasına yol açar.


const view = await createPaywallView(paywall);

// Optional: handle paywall events (close, purchase, restore, etc)
// view.setEventHandlers({ ... });

try {
  await view.present();
} catch (error) {
  // handle the error
}
Important

setEventHandlers’ı birden çok kez çağırmak, sağladığınız işleyicileri geçersiz kılar; söz konusu belirli olaylar için hem varsayılan hem de önceden ayarlanmış işleyicilerin yerini alır.

iOS sunum stilini yapılandırın

Paywall’ın iOS’ta nasıl sunulacağını, present() metoduna iosPresentationStyle parametresini ileterek yapılandırın. Parametre 'full_screen' (varsayılan) veya 'page_sheet' değerlerini kabul eder.

try {
  await view.present({ iosPresentationStyle: 'page_sheet' });
} catch (error) {
  // handle the error
}

Geliştirici tanımlı zamanlayıcı kullanma

Mobil uygulamanızda geliştirici tanımlı zamanlayıcılar kullanmak için, timerId’yi kullanın; bu örnekte, Adapty kontrol panelinde ayarladığınız geliştirici tanımlı zamanlayıcının Timer ID’si olan CUSTOM_TIMER_NY. Bu, uygulamanızın zamanlayıcıyı 13d 09h 03m 34s gibi doğru değerle dinamik olarak güncellemesini sağlar (zamanlayıcının bitiş zamanı, örneğin Yılbaşı Günü, eksi mevcut zaman olarak hesaplanır).

Bu örnekte, CUSTOM_TIMER_NY, Adapty kontrol panelinde ayarladığınız geliştirici tanımlı zamanlayıcının Timer ID’sidir. timerResolver, uygulamanızın zamanlayıcıyı 13d 09h 03m 34s gibi doğru değerle dinamik olarak güncellemesini sağlar (zamanlayıcının bitiş zamanı, örneğin Yılbaşı Günü, eksi mevcut zaman olarak hesaplanır).

Dialog gösterme

Android’de bir paywall view sunulduğunda, yerel uyarı dialogları yerine bu metodu kullanın. Android’de normal RN uyarıları paywall view’ın arkasında kalır ve kullanıcılar tarafından görülemez. Bu metot, tüm platformlarda paywallın üzerinde dialog’un düzgün şekilde sunulmasını sağlar.

try {
  const action = await view.showDialog({
    title: 'Close paywall?',
    content: 'You will lose access to exclusive offers.',
    primaryActionTitle: 'Stay',
    secondaryActionTitle: 'Close',
  });

  if (action === 'secondary') {
    // User confirmed - close the paywall
    await view.dismiss();
  }
  // If primary - do nothing, user stays
} catch (error) {
  // handle error
}

Bir aboneliği diğeriyle değiştirme

Bir kullanıcı Android’de başka bir abonelik aktifken yeni bir abonelik satın almaya çalıştığında, paywall view’ı oluştururken abonelik güncelleme parametrelerini ileterek yeni satın almanın nasıl işleneceğini kontrol edebilirsiniz. Mevcut aboneliği yenisiyle değiştirmek için createPaywallView’de oldSubVendorProductId ve prorationMode parametreleriyle birlikte productPurchaseParams kullanın.


const productPurchaseParams = paywall.productIdentifiers.map((productId) => {
  let params = {};
  if (Platform.OS === 'android') {
    params.android = {
      subscriptionUpdateParams: {
        oldSubVendorProductId: 'PRODUCT_ID_OF_THE_CURRENT_ACTIVE_SUBSCRIPTION',
        prorationMode: 'with_time_proration',
      },
    };
  }
  return { productId, params };
});

const view = await createPaywallView(paywall, { productPurchaseParams });

Sorun giderme

Paywallın üst kısmındaki görsel katman (Android)

Note

Bu ayar React Native SDK 3.15.5’ten itibaren desteklenmektedir ve yalnızca bare React Native projelerinde kullanılabilir.

Expo yönetilen iş akışı kullanıyorsanız bu Android kaynağını doğrudan ekleyemezsiniz. Bu ayarı uygulamak için, ilgili Android kaynağını ekleyen özel bir Expo config plugin oluşturmanız ve bunu app.config.js’e kaydetmeniz gerekir. Bunun nedeni Expo’nun yerel Android projesini sizin adınıza yönetmesidir.

AdaptyPaywallView durum çubuğunun arkasına uzanmıyorsa, üst kısmında yine de görsel bir kaplama görünebilir. Onu kaldırmak için uygulamanıza aşağıdaki boolean kaynağını ekleyin:

  1. android/app/src/main/res/values konumuna gidin. bools.xml dosyası yoksa oluşturun.

  2. Aşağıdaki kaynağı ekleyin:

<resources>
    <bool name="adapty_paywall_enable_safe_area_paddings">false</bool>
</resources>

Değişikliklerin uygulamanızdaki tüm paywall’lar için genel olarak geçerli olduğunu unutmayın.