フローとペイウォールの取得 - iOS

getFlow で取得される内容
✦
フロー Flow & Paywall Builder で作成——デバイス上でネイティブにレンダリングされ、WebView は不要
✦
旧 Paywall Builder のペイウォール 旧 Paywall Builder で作成された既存のすべてのコンテンツ

フローをデザインしたら、モバイルアプリで表示できます。最初のステップは、プレースメントに関連付けられたフローまたはペイウォールとそのビュー設定を取得することです。詳細は以下をご覧ください。

Tip

実際のアプリへの Adapty SDK の統合例を見てみたいですか?ペイウォールの表示、購入処理など基本的な機能の完全なセットアップを示すサンプルアプリをご確認ください。

始める前に

必要なもの:

フロー/ペイウォールの取得

ビルダーでフローやペイウォールを作成した場合、それをモバイルアプリのコードでレンダリングしてユーザーに表示する方法を気にする必要はありません。フローやペイウォールには、表示する内容と表示方法の両方が含まれています。ただし、プレースメントからIDを取得し、ビュー設定を確認した上で、モバイルアプリで表示する必要があります。

フローまたはペイウォールと、そのビュー設定をできるだけ早い段階で取得してください。理想的には、表示するよりずっと前に取得しておくことをおすすめします。ビュー設定を取得した時点で、SDK はバックグラウンドで画像のダウンロードとキャッシュを開始します。早めに取得するほど、ダウンロードが完了するまでの時間を十分に確保できます。フローまたはペイウォールを表示する頃には、設定と画像がすでにキャッシュされ、すぐに表示できる状態になっています。

Tip

複数のプレースメントを一度にウォームアップするには、preloadFlows(iOS SDK 4.1+)を呼び出してください。プレースメントの JSON のみをキャッシュするため、レイアウトや画像を取得するにはビュー設定を別途フェッチする必要があります。

フローまたはペイウォールを取得するには、getFlow メソッドを使用します:

パラメーター:

パラメータ必須/任意説明
placementId必須取得したいプレースメントの識別子。Adapty ダッシュボードでプレースメントを作成する際に指定した値です。
fetchPolicyデフォルト: .reloadRevalidatingCacheData

fetchPolicy は SDK がどのレイヤーを最初に参照するかを設定するものであり、キャッシュを使用できるかどうかを制御するものではありません。デフォルトでは SDK はまずサーバーにアクセスし、そのリクエストが失敗した場合にキャッシュされたデータを返します。ユーザーが常に最新のデータを取得できるため、このオプションを推奨します。

ただし、ユーザーが不安定なインターネット環境を使用していると考えられる場合は、.returnCacheDataElseLoad の使用を検討してください。これは順序を逆にして、まずキャッシュを参照し、何もキャッシュされていない場合のみサーバーにアクセスします。ユーザーが最新のデータを取得できない可能性がありますが、インターネット接続が不安定な状況でも読み込み時間が短縮されます。キャッシュは定期的に更新されるため、ネットワークリクエストを避けるためにセッション中に使用しても安全です。

3つ目のポリシー .returnCacheDataIfNotExpiredElseLoad(maxAge:) は、その中間に位置します。キャッシュされたコピーが maxAge 秒より新しい場合はキャッシュを最初に参照し、古くなった場合はサーバーにアクセスします。

キャッシュはアプリを再起動しても保持され、アプリの再インストール時または手動でクリアした場合にのみ削除されることに注意してください。

Adapty SDK はペイウォールをローカルに2つのレイヤーで保存します。上記の定期更新されるキャッシュとフォールバックペイウォールです。また、ペイウォールをより速く取得するために CDN を使用し、CDN が利用できない場合に備えてスタンドアロンのフォールバックサーバーも使用します。このシステムは、インターネット接続が不安定な状況でも信頼性を確保しつつ、常に最新バージョンのペイウォールを取得できるよう設計されています。

loadTimeoutデフォルト: 5秒

この値はこのメソッドのタイムアウト時間を制限します。タイムアウトに達した場合、キャッシュされたデータまたはローカルフォールバックが返されます。

内部で異なるリクエストが実行される場合があるため、まれにこのメソッドが loadTimeout で指定した時間よりわずかに遅くタイムアウトすることがある点に注意してください。

レスポンスパラメーター:

パラメーター説明
Flowプレースメント、識別子(id、variationId)、バリアント名(variationName、省略可能、SDK 4.2+)、名前、ペイウォールのバリアント(paywalls)、リモートコンフィグ、およびフローにビュー設定が含まれているかどうかを示す hasViewConfiguration フラグを含む AdaptyFlow オブジェクト。事前読み込み、カスタム UI、またはプログラムによるチェックのために実際のプロダクトを取得するには、getPaywallProducts(flow:) を呼び出してください。

ビュー設定の取得

フローまたはペイウォールを取得したら、flow.hasViewConfiguration でビュー設定が含まれているかどうかを確認します。このフラグは、プレースメントが Adapty ダッシュボードでどのように設計されたかを示します。

  • true — プレースメントが Flow & Paywall Builder(フロー)または 旧ペイウォールビルダー(ペイウォール)で設計されています。Adapty が UI をレンダリングします。引き続き以下の手順でビュー設定を取得し、フローまたはペイウォールを表示してください。
  • false — プレースメントはビルダー UI を持たないカスタムペイウォールです。

getFlowConfiguration メソッドを使用してビュー設定を読み込みます。


guard flow.hasViewConfiguration else {
    // handle as remote config paywall
    return
}

let flowConfiguration = try await AdaptyUI.getFlowConfiguration(forFlow: flow)

パラメーター:

パラメーター必須/任意説明
forFlowrequiredAdapty.getFlow で取得した AdaptyFlow オブジェクト。
locale

optional

default: nil

ペイウォールのローカライズの識別子。- で区切られた1つまたは2つのサブタグを持つ言語コードで指定します(例:en、pt-br)。ローカライズとロケールコードを参照してください。
customLayoutId

optional

default: nil

SDK 4.1+

フローのレイアウト設定における特定レイアウトのカスタムID。SDKがデバイスの種類や画面サイズに基づいて自動選択するレイアウトの代わりに、このIDで指定したレイアウトをレンダリングする場合に使用します。IDに一致するレイアウトが存在しない場合、no-view-configuration エラーで呼び出しが失敗します。フロー&ペイウォールビルダーではまだカスタムレイアウトIDを付与できないため、現時点では未設定のままにしてください。
loadTimeoutdefault: 5 secこのメソッドのタイムアウト上限を設定します。タイムアウトに達した場合、キャッシュされたデータまたはローカルフォールバックが返されます。内部で複数のリクエストが発生する場合があるため、まれに loadTimeout で指定した時間よりも若干遅れてタイムアウトすることがあります。
productsoptional画面上のプロダクトの表示タイミングを最適化するために AdaptyPaywallProduct オブジェクトの配列を指定します。nil を渡した場合、AdaptyUI が必要なプロダクトを自動的に取得します。
systemRequestsHandleroptionalフローのアクションによってトリガーされるシステム権限やレビューリクエストを処理するための、AdaptySystemRequestsHandler に準拠したオブジェクト。フローにそのようなアクションが含まれる場合にのみ必要です。
assetsResolveroptionalフロー/ペイウォール内の画像や動画を上書きする [String: AdaptyCustomAsset] 辞書。アセットのカスタマイズを参照してください。
timerResolveroptional開発者が定義したタイマーの終了日時を提供する、AdaptyTimerResolver に準拠したオブジェクト。開発者定義タイマーの設定を参照してください。

読み込みが完了したら、フロー/ペイウォールを表示します。

デフォルトオーディエンスのフローまたはペイウォールを取得して高速化する

通常、フローやペイウォールはほぼ瞬時に取得されるため、このプロセスの高速化を特に気にする必要はありません。ただし、オーディエンスやプレースメントが多数あり、ユーザーのインターネット接続が不安定な場合は、フローやペイウォールの取得に想定以上の時間がかかることがあります。そのような状況では、何も表示しないよりもスムーズなユーザー体験を提供するために、デフォルトのフローまたはペイウォールを表示したいと思うかもしれません。

これに対処するために、getFlowForDefaultAudience メソッドを使用できます。このメソッドは、指定したプレースメントの All Users オーディエンス向けのフローまたはペイウォールを取得します。ただし、推奨アプローチは getFlow メソッドでフローまたはペイウォールを取得することであり、その詳細は上記のペイウォール情報の取得セクションをご確認ください。

Warning

getFlow を推奨する理由

getFlowForDefaultAudience メソッドにはいくつかの重大な欠点があります:

  • 後方互換性の問題: 異なるアプリバージョン(現在と将来)で別々のペイウォールを表示する必要がある場合、課題が生じる可能性があります。現在の(レガシー)バージョンに対応したペイウォールを設計するか、現在の(レガシー)バージョンのユーザーがレンダリングされないペイウォールで問題が発生することを許容するかのどちらかを選択することになります。
  • ターゲティングの喪失: すべてのユーザーに All Users オーディエンス向けに設計された同じペイウォールが表示されるため、パーソナライズされたターゲティング(国、マーケティングアトリビューション、独自のカスタム属性に基づくものを含む)が失われます。

これらのデメリットを許容してでもフローやペイウォールの取得を高速化したい場合は、以下のように getFlowForDefaultAudience メソッドを使用してください。そうでない場合は、上記で説明した getFlow を使用してください。

Adapty.getFlowForDefaultAudience(placementId: "YOUR_PLACEMENT_ID") { result in
    switch result {
        case let .success(flow):
            // the requested flow
        case let .failure(error):
            // handle the error
    }
}
パラメーター必須 / 任意説明
placementId必須プレースメントの識別子。Adapty ダッシュボードでプレースメントを作成したときに指定した値です。
fetchPolicyデフォルト: .reloadRevalidatingCacheData

fetchPolicy は、SDK がキャッシュを使用できるかどうかではなく、どのレイヤーを最初に読み取るかを設定します。デフォルトでは、SDK はまずサーバーにアクセスし、リクエストが失敗した場合にキャッシュデータを返します。ユーザーが常に最新のデータを受け取れるため、このバリアントを推奨します。

ただし、ユーザーが不安定なインターネット環境にいると考えられる場合は、.returnCacheDataElseLoad の使用を検討してください。これは順序を逆にして、まずキャッシュを読み取り、何もキャッシュされていない場合のみサーバーにアクセスします。ユーザーが最新のデータを取得できない場合もありますが、インターネット接続がどれだけ不安定でも、読み込み時間が速くなります。キャッシュは定期的に更新されるため、ネットワークリクエストを避けるためにセッション中に使用しても安全です。

3 つ目のポリシー .returnCacheDataIfNotExpiredElseLoad(maxAge:) は、この 2 つの中間に位置します。キャッシュされたコピーが maxAge 秒より新しい場合はキャッシュを先に読み取り、古くなった場合はサーバーにアクセスします。

キャッシュはアプリを再起動しても保持され、アプリを再インストールするか手動でクリーンアップした場合にのみクリアされます。

アセットのカスタマイズ

ペイウォール/フローの画像や動画をカスタマイズするには、カスタムアセットを実装します。

ヒーロー画像と動画には事前定義済みのID(hero_imageとhero_video)が割り当てられています。カスタムアセットバンドルでは、これらのIDを使って各要素を指定し、動作をカスタマイズします。

その他の画像や動画については、Adapty ダッシュボードでカスタムIDを設定する必要があります。

たとえば、次のようなことができます。

  • 一部のユーザーに別の画像や動画を表示する。
  • リモートのメイン画像の読み込み中にローカルのプレビュー画像を表示する。
  • 動画再生前にプレビュー画像を表示する。
  • アプリにバンドルされたメディアを表示することで、最初の画面をダウンロードなしでレンダリングする。アプリバンドルからの最初の画面メディアを表示するを参照してください。
  • 動画のピクセル解像度を指定することで、動画の読み込み前にプレイヤーがレイアウトスペースを確保できるようにする(アスペクト比 = width / height)。スキップする場合は nil を渡してください。

Here’s an example of how you can provide custom assets via a simple dictionary:

let customAssets: [String: AdaptyCustomAsset] = [
    // Show a local image using a custom ID
    "custom_image": .image(
        .uiImage(value: UIImage(named: "image_name")!)
    ),

    // Show a local preview image while a remote main image is loading
    "hero_image": .image(
        .remote(
            url: URL(string: "https://example.com/image.jpg")!,
            preview: UIImage(named: "preview_image")
        )
    ),

    // Show a local video with a preview image and a known resolution
    "hero_video": .video(
        .file(
            url: Bundle.main.url(forResource: "custom_video", withExtension: "mp4")!,
            preview: .uiImage(value: UIImage(named: "video_preview")!),
            resolution: CGSize(width: 1080, height: 1920)
        )
    ),
]

let flowConfig = try await AdaptyUI.getFlowConfiguration(
    forFlow: flow,
    assetsResolver: customAssets
)
Note

アセットが見つからない場合、ペイウォール/フローはデフォルトの外観にフォールバックします。

開発者定義タイマーの設定

モバイルアプリでカスタムタイマーを使用するには、AdaptyTimerResolver プロトコルに準拠したオブジェクトを作成します。このオブジェクトは、各カスタムタイマーのレンダリング方法を定義します。必要であれば、このプロトコルにすでに準拠している [String: Date] ディクショナリを直接使用することもできます。以下に例を示します:

@MainActor
struct AdaptyTimerResolverImpl: AdaptyTimerResolver {
    func timerEndAtDate(for timerId: String) -> Date {
        switch timerId {
        case "CUSTOM_TIMER_6H":
            Date(timeIntervalSinceNow: 3600.0 * 6.0) // 6 hours
        case "CUSTOM_TIMER_NY":
            Calendar.current.date(from: DateComponents(year: 2025, month: 1, day: 1)) ?? Date(timeIntervalSinceNow: 3600.0)
        default:
            Date(timeIntervalSinceNow: 3600.0) // 1 hour
        }
    }
}

この例では、CUSTOM_TIMER_NY と CUSTOM_TIMER_6H は、Adapty ダッシュボードで設定した開発者定義タイマーの Timer ID です。timerResolver により、アプリは各タイマーを正しい値で動的に更新できます。例えば:

  • CUSTOM_TIMER_NY: 元日など、タイマーの終了までの残り時間。
  • CUSTOM_TIMER_6H: ユーザーがペイウォールを開いてから始まった6時間のうち、残りの時間。

Adapty ダッシュボードのペイウォールビルダーでペイウォールのビジュアルデザインを作成したら、それをモバイルアプリに表示できます。最初のステップは、以下の説明に従ってプレースメントに関連付けられたペイウォールとそのビュー設定を取得することです。

このトピックはペイウォールビルダーでカスタマイズされたペイウォールに関するものです。ペイウォールを手動で実装する場合は、リモートコンフィグペイウォール用のペイウォールとプロダクトの取得を参照してください。

Tip

Adapty SDK をモバイルアプリに統合した実際の例を見たい方は、サンプルアプリをご覧ください。ペイウォールの表示、購入処理、その他の基本的な機能を含む完全なセットアップを確認できます。

モバイルアプリでペイウォールを表示する前に
  1. Adapty ダッシュボードでプロダクトを作成する。
  2. Adapty ダッシュボードでペイウォールを作成し、プロダクトを追加する。
  3. Adapty ダッシュボードでプレースメントを作成し、ペイウォールを追加する。
  4. モバイルアプリに Adapty SDK をインストールする。

ペイウォールビルダーで作成したペイウォールを取得する

ペイウォールビルダーを使ってペイウォールをデザインした場合、ユーザーに表示するためのレンダリングコードをアプリに書く必要はありません。このようなペイウォールには、表示する内容と表示方法の両方が含まれています。ただし、プレースメントを通じてペイウォールのIDを取得し、ビュー設定を取得してから、アプリ内に表示する必要があります。

最適なパフォーマンスを確保するために、ペイウォールとそのビュー設定をできるだけ早く取得し、ユーザーに表示する前に画像のダウンロードに十分な時間を確保することが重要です。

ペイウォールを取得するには、getPaywall メソッドを使用します:

パラメーター:

パラメータ必須/任意説明
placementId必須取得したいプレースメントの識別子。Adapty ダッシュボードでプレースメントを作成する際に指定した値です。
locale

任意

デフォルト: en

ペイウォールのローカライズ識別子。マイナス(-)文字で区切られた1つまたは2つのサブタグで構成された言語コードを指定します。最初のサブタグは言語、2番目は地域を表します。

例: en は英語、pt-br はブラジルポルトガル語を表します。

ロケールコードとその推奨使用方法については、ローカライズとロケールコードを参照してください。

fetchPolicyデフォルト: .reloadRevalidatingCacheData

fetchPolicy は、SDKがキャッシュを使用できるかどうかではなく、どのレイヤーを最初に読み取るかを設定します。デフォルトでは、SDKはまずサーバーにアクセスし、リクエストが失敗した場合にキャッシュデータを返します。これにより常に最新のデータをユーザーに届けられるため、この設定を推奨します。

ただし、ユーザーが不安定なインターネット環境にいる可能性がある場合は、.returnCacheDataElseLoad の使用を検討してください。これは順序を逆にした設定で、まずキャッシュを読み取り、キャッシュがない場合のみサーバーにアクセスします。ユーザーは必ずしも最新のデータを受け取れるわけではありませんが、インターネット接続が不安定な場合でも読み込みが速くなります。キャッシュは定期的に更新されるため、セッション中のネットワークリクエストを回避する目的で使用しても安全です。

3つ目のポリシー .returnCacheDataIfNotExpiredElseLoad(maxAge:) は、この2つの中間に位置します。キャッシュが maxAge 秒より新しい場合はキャッシュを先に読み取り、古くなった場合はサーバーにアクセスします。

キャッシュはアプリの再起動後も保持され、アプリの再インストール時または手動でクリアした場合にのみ削除されます。

Adapty SDK はペイウォールをローカルに2つのレイヤーで保存します。1つは上記の定期更新キャッシュ、もう1つはフォールバックペイウォールです。また、ペイウォールをより高速に取得するために CDN を使用し、CDN が利用できない場合に備えてスタンドアロンのフォールバックサーバーも用意しています。このシステムは、インターネット接続が不安定な場合でも信頼性を確保しながら、常に最新バージョンのペイウォールを取得できるように設計されています。

loadTimeoutデフォルト: 5秒

このメソッドのタイムアウト上限を設定します。タイムアウトに達した場合、キャッシュデータまたはローカルフォールバックが返されます。

なお、このメソッドは内部で複数のリクエストを行う場合があるため、まれに loadTimeout で指定した時間よりわずかに遅れてタイムアウトすることがあります。

レスポンスパラメーター:

パラメーター説明
PaywallプロダクトIDのリスト、ペイウォールの識別子、リモートコンフィグ、およびその他のプロパティを含む AdaptyPaywall オブジェクト。

ペイウォールビルダーで作成したペイウォールのビュー設定を取得する

Important

ペイウォールビルダーで Show on device トグルを有効にしてください。このオプションがオンになっていない場合、ビュー設定を取得できません。

ペイウォールを取得したら、ビュー設定が含まれているかどうかを確認してください。ビュー設定が存在する場合は、そのペイウォールがペイウォールビルダーで作成されたことを意味します。これにより、ペイウォールの表示方法が決まります。ビュー設定がある場合はペイウォールビルダーのペイウォールとして扱い、ない場合はリモートコンフィグのペイウォールとして処理してください。

getPaywallConfiguration メソッドを使って、ビュー設定を読み込みます。


guard paywall.hasViewConfiguration else {
    //  use your custom logic
    return
}

do {
    let paywallConfiguration = try await AdaptyUI.getPaywallConfiguration(
            forPaywall: paywall,
            products: products
    )
    // use loaded configuration
} catch {
    // handle the error
}

パラメーター:

パラメータ必須/任意説明
paywall必須対象のペイウォールのコントローラーを取得するための AdaptyPaywall オブジェクト。
loadTimeoutデフォルト: 5秒このメソッドのタイムアウト上限を設定します。タイムアウトに達した場合、キャッシュされたデータまたはローカルのフォールバックが返されます。内部で複数のリクエストが発生する場合があるため、まれに loadTimeout で指定した時間よりもわずかに遅れてタイムアウトすることがあります。
products任意画面上でのプロダクト表示タイミングを最適化するために、AdaptyPaywallProduct オブジェクトの配列を指定します。nil を渡した場合、AdaptyUI が自動的に必要なプロダクトを取得します。
Note

複数の言語をサポートする場合は、ペイウォールにローカライゼーションを追加してください。使用するコードについては、ローカライゼーションとロケールコードを参照してください。

読み込みが完了したら、ペイウォールを表示します。

デフォルトオーディエンス向けペイウォールを取得してより速く表示する

通常、ペイウォールはほぼ瞬時に取得されるため、速度を気にする必要はありません。ただし、オーディエンスやペイウォールの数が多く、ユーザーのインターネット接続が不安定な場合は、ペイウォールの取得に想定以上の時間がかかることがあります。そのような状況では、ペイウォールをまったく表示しないよりも、デフォルトのペイウォールを表示してスムーズなユーザー体験を提供することを検討するとよいでしょう。

この問題に対処するために、getPaywallForDefaultAudience メソッドを使用できます。このメソッドは、指定されたプレースメントの All Users オーディエンス向けペイウォールを取得します。ただし、推奨されるアプローチは getPaywall メソッドでペイウォールを取得することであり、詳細は上記の ペイウォール情報の取得 セクションをご覧ください。

Warning

getPaywall を推奨する理由

getPaywallForDefaultAudience メソッドにはいくつかの重大な欠点があります:

  • 後方互換性の問題: 異なるアプリバージョン(現行バージョンと将来のバージョン)に対して異なるペイウォールを表示する必要がある場合、課題が生じる可能性があります。現行(レガシー)バージョンに対応したペイウォールを設計するか、現行(レガシー)バージョンのユーザーがレンダリングされないペイウォールに遭遇するリスクを許容するかのどちらかを選択しなければなりません。
  • ターゲティングの喪失: すべてのユーザーが All Users オーディエンス向けに設計された同じペイウォールを見ることになるため、パーソナライズされたターゲティング(国、マーケティングアトリビューション、独自のカスタム属性に基づくものを含む)が失われます。

これらのデメリットを受け入れてでもペイウォールの取得を高速化したい場合は、以下のように getPaywallForDefaultAudience メソッドを使用してください。そうでない場合は、上記で説明した getPaywall を使用してください。

Adapty.getPaywallForDefaultAudience(placementId: "YOUR_PLACEMENT_ID", locale: "en") { result in
    switch result {
        case let .success(paywall):
            // the requested paywall
        case let .failure(error):
            // handle the error
    }
}
Note

getPaywallForDefaultAudience メソッドは iOS SDK バージョン 2.11.2 以降で利用可能です。

パラメーター必須/任意説明
placementId必須プレースメントの識別子。Adapty ダッシュボードでプレースメントを作成する際に指定した値です。
locale

任意

デフォルト: en

ペイウォールのローカライズの識別子。マイナス(-)文字で区切られた1つ以上のサブタグで構成される言語コードを指定します。最初のサブタグは言語、2番目のサブタグは地域を表します。

例: en は英語、pt-br はブラジルポルトガル語を表します。

ロケールコードの詳細および推奨する使い方については、ローカライズとロケールコードをご覧ください。

fetchPolicyデフォルト: .reloadRevalidatingCacheData

fetchPolicy は、SDKがどのレイヤーを最初に読み取るかを設定するものであり、キャッシュを使用できるかどうかを設定するものではありません。デフォルトでは、SDKはまずサーバーにアクセスし、リクエストが失敗した場合にキャッシュデータを返します。このバリアントを推奨するのは、ユーザーが常に最新のデータを取得できるためです。

ただし、ユーザーが不安定なインターネット環境にある可能性がある場合は、.returnCacheDataElseLoad の使用を検討してください。これは順序を逆にして、まずキャッシュを読み取り、キャッシュが存在しない場合にのみサーバーにアクセスします。絶対最新のデータを取得できない場合がありますが、インターネット接続が不安定でも読み込み時間が短縮されます。キャッシュは定期的に更新されるため、セッション中にネットワークリクエストを避けるためにキャッシュを使用しても安全です。

3番目のポリシー .returnCacheDataIfNotExpiredElseLoad(maxAge:) は、両者の中間に位置します。キャッシュされたコピーが maxAge 秒より新しい間はキャッシュを最初に読み取り、それより古くなるとサーバーにアクセスします。

キャッシュはアプリを再起動しても保持され、アプリの再インストール時または手動でクリーンアップした場合にのみクリアされます。

アセットのカスタマイズ

ペイウォールの画像や動画をカスタマイズするには、カスタムアセットを実装します。

ヒーロー画像と動画には、hero_image と hero_video という定義済みIDがあります。カスタムアセットバンドルでは、これらのIDを使って各要素を指定し、動作をカスタマイズできます。

その他の画像や動画については、Adapty ダッシュボードでカスタムIDを設定する必要があります。

たとえば、次のようなことができます。

  • 一部のユーザーに別の画像や動画を表示する。
  • リモートのメイン画像の読み込み中に、ローカルのプレビュー画像を表示する。
  • 動画を再生する前にプレビュー画像を表示する。
Important

この機能を使用するには、Adapty iOS SDK をバージョン 3.7.0 以上にアップデートしてください。

カスタムアセットをシンプルな辞書形式で提供する方法の例を示します:

let customAssets: [String: AdaptyCustomAsset] = [
    // Show a local image using a custom ID
    "custom_image": .image(
        .uiImage(value: UIImage(named: "image_name")!)
    ),

    // Show a local preview image while a remote main image is loading
    "hero_image": .image(
        .remote(
            url: URL(string: "https://example.com/image.jpg")!,
            preview: UIImage(named: "preview_image")
        )
    ),

    // Show a local video with a preview image
    "hero_video": .video(
        .file(
            url: Bundle.main.url(forResource: "custom_video", withExtension: "mp4")!,
            preview: .uiImage(value: UIImage(named: "video_preview")!)
        )
    ),
]

let paywallConfig = try await AdaptyUI.getPaywallConfiguration(
    forPaywall: paywall,
    assetsResolver: customAssets
)
Note

アセットが見つからない場合、ペイウォールはデフォルトの外観にフォールバックします。

デベロッパー定義タイマーの設定

モバイルアプリでカスタムタイマーを使用するには、AdaptyTimerResolver プロトコルに準拠したオブジェクトを作成します。このオブジェクトは、各カスタムタイマーのレンダリング方法を定義します。[String: Date] ディクショナリはすでにこのプロトコルに準拠しているため、直接使用することもできます。以下に例を示します。

@MainActor
struct AdaptyTimerResolverImpl: AdaptyTimerResolver {
    func timerEndAtDate(for timerId: String) -> Date {
        switch timerId {
        case "CUSTOM_TIMER_6H":
            Date(timeIntervalSinceNow: 3600.0 * 6.0) // 6 hours
        case "CUSTOM_TIMER_NY":
            Calendar.current.date(from: DateComponents(year: 2025, month: 1, day: 1)) ?? Date(timeIntervalSinceNow: 3600.0)
        default:
            Date(timeIntervalSinceNow: 3600.0) // 1 hour
        }
    }
}

この例では、CUSTOM_TIMER_NY と CUSTOM_TIMER_6H は、Adapty ダッシュボードで設定した開発者定義タイマーの Timer ID です。timerResolver により、アプリは各タイマーを正しい値で動的に更新できます。例えば:

  • CUSTOM_TIMER_NY: 元日など、タイマー終了までの残り時間。
  • CUSTOM_TIMER_6H: ユーザーがペイウォールを開いてから始まった6時間のうち、残り時間。