前提条件
Singular SDK を統合する」の手順を完了してください:この統合を進める前に、「計画と前提条件」のステップを完了してください。
重要:これらの前提条件は、Singular SDKを統合する際に必要です。
インストール
お好みのインストール方法を選択してください。ほとんどのプロジェクトにはCocoaPodsをお勧めします。
即決:
- すでにCocoaPodsをお使いですか?方法1を使用
- SPMのみのプロジェクト?方法2を使用
- パッケージマネージャを使用しない?方法3を使用
インストール方法
方法1:CocoaPods(推奨)
必要条件
- CocoaPodsのインストール(インストールガイド)
- プロジェクト・ディレクトリへのターミナル・アクセス
インストールのステップ
-
Podfileを初期化します(すでにPodfileがある場合はスキップしてください):
cd /path/to/your/project pod init -
Singular SDKをPodfileに追加します:
platform :ios, '12.0' target 'YourAppName' do use_frameworks! # Singular SDK pod 'Singular-SDK' end -
依存関係をインストールします:
pod install -
ワークスペースを開きます:今後は、
.xcodeprojの代わりに.xcworkspaceを開いてください。 - Swiftプロジェクトのみ: ブリッジングヘッダーを作成する(下記参照
方法2: Swiftパッケージマネージャー
インストールステップ
- Xcodeでファイル → パッケージの追加
-
リポジトリのURLを入力:
https://github.com/singular-labs/Singular-iOS-SDK - バージョンを選択し、パッケージの追加をクリック
-
必要なフレームワークを追加する:
Build Phases → Link Binary with Librariesに進み、追加する:-
必要なライブラリをリンクする:
Build Phases → Link Binary With Librariesに進み、以下を追加する:- Libsqlite3.0.tbd
- SystemConfiguration.framework
- Security.フレームワーク
- Libz.tbd
- AdSupport.framework
- WebKit.フレームワーク
- StoreKit.フレームワーク
- AdServices.framework (オプションとしてマーク)
-
必要なライブラリをリンクする:
- Swift プロジェクトのみ: ブリッジング・ヘッダーを作成する(以下を参照
方法3:フレームワークの手動インストール
いつ使うか:CocoaPodsやSPMを使用できない場合にのみ、この方法を使用してください。
フレームワークをダウンロードする:
- Xcode 12+:.xcframework をダウンロード
- Xcode 11以下:.framework をダウンロード
インストール手順
- ダウンロードしたフレームワークを解凍する
- Xcodeでプロジェクトを右クリック →[プロジェクト]にファイルを追加
- Create Groupsを選択し、フレームワークフォルダを追加する。
-
必要なライブラリをリンクする:
Build Phases → Link Binary With Librariesに進み、追加する:- Libsqlite3.0.tbdを追加する。
- SystemConfiguration.framework
- Security.フレームワーク
- Libz.tbd
- AdSupport.framework
- WebKit.フレームワーク
- StoreKit.フレームワーク
- AdServices.framework (オプションとしてマーク)
-
フレームワークを埋め込む:
General → Frameworks, Libraries, and Embedded Contentに移動します。
SingularフレームワークをEmbed & Signに設定する
Swiftブリッジングヘッダー
重要:CocoaPodsまたはSPMを使用するSwiftプロジェクトに必要。
-
ヘッダーファイルを作成する:
Xcode →ファイル → 新規作成 → ファイル → ヘッダーファイル
名前をYourProjectName-Bridging-Header.hとする。 -
インポートを追加する:
#import <Singular/Singular.h> -
ビルド設定でリンクする:
ビルド設定 → Objective-C ブリッジヘッダ
に設定する:YourProjectName/YourProjectName-Bridging-Header.h
SDKの設定と初期化
コンフィギュレーション・オブジェクトを作成し、アプリのエントリー・ポイントでSDKを初期化します。
コンフィギュレーション・オブジェクトの作成
基本構成
SDK クレデンシャルとオプション機能でSingularConfig オブジェクトを作成します。この構成は、すべてのアプリアーキテクチャで共通です。
クレデンシャルを取得します:SDKキーとSDKシークレットをSingularプラットフォームのDeveloper Tools → SDK Integrationで見つけてください。
// MARK: - Singular Configuration
private func getConfig() -> SingularConfig? {
// Create config with your credentials
guard let config = SingularConfig(
apiKey: "YOUR_SDK_KEY",
andSecret: "YOUR_SDK_SECRET"
) else {
return nil
}
// OPTIONAL: Wait for ATT consent (if showing ATT prompt)
// Remove this line if NOT using App Tracking Transparency
config.waitForTrackingAuthorizationWithTimeoutInterval = 300
// OPTIONAL: Support custom ESP domains for deep links
config.espDomains = ["links.your-domain.com"]
// OPTIONAL: Handle deep links
config.singularLinksHandler = { params in
if let params = params {
self.handleDeeplink(params)
}
}
return config
}
// MARK: - OPTIONAL: Deep link handler implementation
private func handleDeeplink(_ params: SingularLinkParams) {
// Guard clause: Exit if no deep link provided
guard let deeplink = params.getDeepLink() else {
return
}
// Extract deep link parameters
let passthrough = params.getPassthrough()
let isDeferred = params.isDeferred()
let urlParams = params.getUrlParameters()
#if DEBUG
// Debug logging only - stripped from production builds
print("Singular Links Handler")
print("Singular deeplink received:", deeplink)
print("Singular passthrough received:", passthrough ?? "none")
print("Singular isDeferred received:", isDeferred ? "YES" : "NO")
print("Singular URL Params received:", urlParams ?? [:])
#endif
// TODO: Navigate to appropriate screen based on deep link
// Add deep link handling code here. Navigate to appropriate screen.
}
#pragma mark - Singular Configuration
- (SingularConfig *)getConfig {
// Create config with your credentials
SingularConfig *config = [[SingularConfig alloc]
initWithApiKey:@"YOUR_SDK_KEY"
andSecret:@"YOUR_SDK_SECRET"];
// OPTIONAL: Wait for ATT consent (if showing ATT prompt)
// Remove this line if NOT using App Tracking Transparency
config.waitForTrackingAuthorizationWithTimeoutInterval = 300;
// OPTIONAL: Support custom ESP domains for deep links
config.espDomains = @[@"links.your-domain.com"];
// OPTIONAL: Handle deep links
config.singularLinksHandler = ^(SingularLinkParams *params) {
[self handleDeeplink:params];
};
return config;
}
#pragma mark - OPTIONAL: Deep link handler implementation
- (void)handleDeeplink:(SingularLinkParams *)params {
// Guard clause: Exit if params is nil
if (!params) {
return;
}
// Guard clause: Exit if no deep link provided
NSString *deeplink = [params getDeepLink];
if (!deeplink) {
return;
}
// Extract deep link parameters
NSString *passthrough = [params getPassthrough];
BOOL isDeferred = [params isDeferred];
NSDictionary *urlParams = [params getUrlParameters];
#ifdef DEBUG
// Debug logging only - stripped from production builds
NSLog(@"Singular Links Handler");
NSLog(@"Singular deeplink received: %@", deeplink);
NSLog(@"Singular passthrough received: %@", passthrough);
NSLog(@"Singular isDeferred received: %@", isDeferred ? @"YES" : @"NO");
NSLog(@"Singular URL Params received: %@", urlParams);
#endif
// TODO: Navigate to appropriate screen based on deep link
// Add deep link handling code here. Navigate to appropriate screen.
}
SKAdNetworkの自動有効化:SDKバージョン12.0.6から、SKAdNetworkはデフォルトで有効になっています。追加の設定は必要ありません。
SDKの初期化
アプリアーキテクチャの選択
アプリのエントリーポイント毎にSDKを初期化します。初期化のパターンはアプリのアーキテクチャによって異なります。
私はどのアーキテクチャを持っていますか?
-
SceneDelegate:あなたのプロジェクトが
SceneDelegate.swiftまたはSceneDelegate.mを持っているか確認してください。 -
SwiftUI:あなたのアプリは
@main struct YourApp: Appで始まります。 - AppDelegateのみ:iOS13以前のアプリまたはSceneDelegateのないアプリ
モダンiOS:SceneDelegate (iOS 13+)
コードを追加する場所 SceneDelegate.swift
またはSceneDelegate.m
初期化するエントリーポイント
-
willConnectTo session- アプリの起動 -
continue userActivity- ユニバーサルリンク -
openURLContexts- ディープリンク・スキーム
import Singular
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
// 1️⃣ App launch
func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
// ANTI-SWIZZLING: Capture deep link parameters IMMEDIATELY before any
// other code runs. This prevents third-party SDKs from intercepting
// or modifying these values.
let userActivity = connectionOptions.userActivities.first
let urlContext = connectionOptions.urlContexts.first
let openUrl = urlContext?.url
#if DEBUG
// Log captured values to detect swizzling interference
print("[SWIZZLE CHECK] UserActivity captured:", userActivity?.webpageURL?.absoluteString ?? "none")
print("[SWIZZLE CHECK] URL Context captured:", openUrl?.absoluteString ?? "none")
print("IDFV:", UIDevice.current.identifierForVendor?.uuidString ?? "N/A")
#endif
// Create window from windowScene
guard let windowScene = scene as? UIWindowScene else { return }
window = UIWindow(windowScene: windowScene)
window?.rootViewController = UIViewController() // Replace with your root VC
window?.makeKeyAndVisible()
// Singular initialization - uses captured values to avoid swizzling conflicts
guard let config = getConfig() else { return }
// Pass Universal Link if available
if let userActivity = userActivity {
config.userActivity = userActivity
}
// Pass URL scheme if available
// CRITICAL for custom URL scheme attribution
if let openUrl = openUrl {
config.openUrl = openUrl
}
// Initialize Singular SDK
Singular.start(config)
}
// 2️⃣ Universal Links
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
guard let config = getConfig() else { return }
config.userActivity = userActivity
// Initialize Singular SDK
Singular.start(config)
}
// 3️⃣ Deep link schemes
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
guard let config = getConfig() else { return }
if let url = URLContexts.first?.url {
config.openUrl = url
}
// Initialize Singular SDK
Singular.start(config)
}
}
#import <Singular/Singular.h>
@implementation SceneDelegate
// 1️⃣ App launch
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session
options:(UISceneConnectionOptions *)connectionOptions {
// ANTI-SWIZZLING: Capture deep link parameters IMMEDIATELY before any
// other code runs. This prevents third-party SDKs from intercepting
// or modifying these values.
NSUserActivity *userActivity =
[[[connectionOptions userActivities]
allObjects] firstObject];
UIOpenURLContext *urlContext =
[[connectionOptions URLContexts]
allObjects].firstObject;
NSURL *openUrl = urlContext.URL;
#ifdef DEBUG
// Log captured values to detect swizzling interference
NSLog(@"[SWIZZLE CHECK] "
"UserActivity captured: %@",
userActivity.webpageURL);
NSLog(@"[SWIZZLE CHECK] "
"URL Context captured: %@",
openUrl);
#endif
// Create window from windowScene
UIWindowScene *windowScene = (UIWindowScene *)scene;
self.window = [[UIWindow alloc] initWithWindowScene:windowScene];
self.window.rootViewController = [[UIViewController alloc] init];
[self.window makeKeyAndVisible];
#ifdef DEBUG
// Print IDFV for testing in SDK Console
NSLog(@"IDFV: %@", [[[UIDevice currentDevice] identifierForVendor] UUIDString]);
#endif
// Singular initialization - uses captured values to avoid swizzling
SingularConfig *config = [self getConfig];
// Pass Universal Link if available
if (userActivity) {
config.userActivity = userActivity;
}
// Pass URL scheme if available
// CRITICAL for custom URL scheme
if (openUrl) {
config.openUrl = openUrl;
}
// Initialize Singular SDK
[Singular start:config];
}
// 2️⃣ Universal Links
- (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity {
// ANTI-SWIZZLING: Capture userActivity immediately at method entry. Called
// when Universal Link is opened while app is running or backgrounded.
NSUserActivity *capturedActivity = userActivity;
#ifdef DEBUG
NSLog(@"[SWIZZLE CHECK] "
"continueUserActivity captured: %@",
capturedActivity.webpageURL);
#endif
SingularConfig *config = [self getConfig];
config.userActivity = capturedActivity;
// Initialize Singular SDK
[Singular start:config];
}
// 3️⃣ Deep link schemes
- (void)scene:(UIScene *)scene openURLContexts:(NSSet *)URLContexts {
// ANTI-SWIZZLING: Capture URL immediately at method entry. Called
// when URL scheme is opened while app is running or backgrounded.
NSURL *capturedUrl =
[[URLContexts allObjects]
firstObject].URL;
#ifdef DEBUG
NSLog(@"[SWIZZLE CHECK] "
"openURLContexts captured: %@",
capturedUrl);
#endif
SingularConfig *config = [self getConfig];
if (capturedUrl) {
config.openUrl = capturedUrl;
}
// Initialize Singular SDK
[Singular start:config];
}
@end
モダンiOS:SwiftUI アプリ (iOS 14+)
コードを追加する場所あなたのメインApp構造体ファイル
初期化するエントリーポイント
-
.onOpenURL(of: scenePhase)- カスタムURLスキームを扱う -
.onContinueUserActivity(of: scenePhase)- ユニバーサルリンク(Singularなディープリンク)を扱う -
.onChange.active- ディープ・リンクが発生していない場合の初回起動時の初期化を処理します。遅延ディープリンクを処理します。
import SwiftUI
import Singular
@main
struct simpleSwiftUIApp: App {
@Environment(\.scenePhase) var scenePhase
@State private var hasInitialized = false
var body: some Scene {
WindowGroup {
ContentView()
// 1️⃣ Handle custom URL schemes (e.g., myapp://path)
.onOpenURL { url in
#if DEBUG
print("[Singular] URL Scheme:", url.absoluteString)
#endif
guard let config = getConfig() else { return }
config.openUrl = url
Singular.start(config)
hasInitialized = true
}
// 2️⃣ Handle Universal Links (e.g., https://links.your-domain.com)
.onContinueUserActivity(NSUserActivityTypeBrowsingWeb) { userActivity in
#if DEBUG
print("[Singular] Universal Link:", userActivity.webpageURL?.absoluteString ?? "none")
#endif
guard let config = getConfig() else { return }
config.userActivity = userActivity
Singular.start(config)
hasInitialized = true
}
}
.onChange(of: scenePhase) { oldPhase, newPhase in
switch newPhase {
case .active:
// 3️⃣ Initialize ONLY on first launch if no deep link occurred
guard !hasInitialized else {
#if DEBUG
print("[Singular] Already initialized, skipping")
#endif
return
}
#if DEBUG
if let idfv = UIDevice.current.identifierForVendor?.uuidString {
print("[Singular] IDFV:", idfv)
}
#endif
guard let config = getConfig() else { return }
Singular.start(config)
hasInitialized = true
case .background:
#if DEBUG
print("[Singular] App backgrounded")
#endif
case .inactive:
#if DEBUG
print("[Singular] App inactive")
#endif
@unknown default:
break
}
}
}
// Add your getConfig() function here
// MARK: - Singular Configuration
private func getConfig() -> SingularConfig? {
// ... (same as above)
}
// Add your handleDeeplink() function here
// MARK: - Deep Link Handler
private func handleDeeplink(_ params: SingularLinkParams) {
// ... (same as above)
}
}
レガシーiOS:AppDelegate (iOS13以前)
コードを追加する場所 AppDelegate.swift
またはAppDelegate.m
初期化するエントリポイント:
-
didFinishLaunchingWithOptions- アプリの起動 -
continue userActivity- ユニバーサルリンク -
open url- ディープリンク・スキーム
import Singular
import UIKit
class AppDelegate: UIResponder, UIApplicationDelegate {
// 1️⃣ App launch
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// ANTI-SWIZZLING: Capture deep link parameters IMMEDIATELY before any
// other code runs. This prevents third-party SDKs from intercepting
// or modifying these values.
let launchUrl = launchOptions?[.url] as? URL
let userActivityDictionary = launchOptions?[.userActivityDictionary] as? [String: Any]
let userActivity = userActivityDictionary?["UIApplicationLaunchOptionsUserActivityKey"] as? NSUserActivity
#if DEBUG
// Log captured values to detect swizzling interference
print("[SWIZZLE CHECK] Launch URL captured:", launchUrl?.absoluteString ?? "none")
print("[SWIZZLE CHECK] UserActivity captured:", userActivity?.webpageURL?.absoluteString ?? "none")
print("IDFV:", UIDevice.current.identifierForVendor?.uuidString ?? "N/A")
#endif
// Singular initialization - uses captured values to avoid swizzling conflicts
guard let config = getConfig() else { return true }
// Pass the entire launchOptions dictionary for Singular's internal processing
config.launchOptions = launchOptions
// Explicitly pass Universal Link if available
// CRITICAL for universal link attribution
if let userActivity = userActivity {
config.userActivity = userActivity
}
// Explicitly pass URL scheme if available
// CRITICAL for custom URL scheme attribution
if let launchUrl = launchUrl {
config.openUrl = launchUrl
}
// Initialize Singular SDK
Singular.start(config)
return true
}
// 2️⃣ Universal Links
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([any UIUserActivityRestoring]?) -> Void) -> Bool {
#if DEBUG
print("[SWIZZLE CHECK] Universal Link handler called:", userActivity.webpageURL?.absoluteString ?? "none")
#endif
guard let config = getConfig() else { return true }
config.userActivity = userActivity
Singular.start(config)
return true
}
// 3️⃣ Deep link schemes
func application(_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
#if DEBUG
print("[SWIZZLE CHECK] URL Scheme handler called:", url.absoluteString)
#endif
guard let config = getConfig() else { return true }
config.openUrl = url
Singular.start(config)
return true
}
// Add your getConfig() function here
// MARK: - Singular Configuration
private func getConfig() -> SingularConfig? {
// ... (same as above)
}
// Add your handleDeeplink() function here
// MARK: - Deep Link Handler
private func handleDeeplink(_ params: SingularLinkParams) {
// ... (same as above)
}
}
#import "AppDelegate.h"
#import <Singular/Singular.h>
@implementation AppDelegate
// 1️⃣ App launch
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// ANTI-SWIZZLING: Capture deep link parameters IMMEDIATELY before any
// other code runs. This prevents third-party SDKs from intercepting
// or modifying these values.
NSURL *launchUrl = [launchOptions objectForKey:UIApplicationLaunchOptionsURLKey];
NSDictionary *userActivityDictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsUserActivityDictionaryKey];
NSUserActivity *userActivity = [userActivityDictionary objectForKey:@"UIApplicationLaunchOptionsUserActivityKey"];
#if DEBUG
// Log captured values to detect swizzling interference
NSLog(@"[SWIZZLE CHECK] Launch URL captured: %@", launchUrl.absoluteString ?: @"none");
NSLog(@"[SWIZZLE CHECK] UserActivity captured: %@", userActivity.webpageURL.absoluteString ?: @"none");
NSLog(@"IDFV: %@", [UIDevice currentDevice].identifierForVendor.UUIDString ?: @"N/A");
#endif
// Singular initialization - uses captured values to avoid swizzling conflicts
SingularConfig *config = [self getConfig];
if (!config) {
return YES;
}
// Pass the entire launchOptions dictionary for Singular's internal processing
config.launchOptions = launchOptions;
// Explicitly pass Universal Link if available
// CRITICAL for universal link attribution
if (userActivity) {
config.userActivity = userActivity;
}
// Explicitly pass URL scheme if available
// CRITICAL for custom URL scheme attribution
if (launchUrl) {
config.openUrl = launchUrl;
}
// Initialize Singular SDK
[Singular start:config];
return YES;
}
// 2️⃣ Universal Links
- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
#if DEBUG
NSLog(@"[SWIZZLE CHECK] Universal Link handler called: %@", userActivity.webpageURL.absoluteString ?: @"none");
#endif
SingularConfig *config = [self getConfig];
if (!config) {
return YES;
}
config.userActivity = userActivity;
[Singular start:config];
return YES;
}
// 3️⃣ Deep link schemes
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
#if DEBUG
NSLog(@"[SWIZZLE CHECK] URL Scheme handler called: %@", url.absoluteString);
#endif
SingularConfig *config = [self getConfig];
if (!config) {
return YES;
}
config.openUrl = url;
[Singular start:config];
return YES;
}
#pragma mark - Singular Configuration
- (SingularConfig *)getConfig {
}
#pragma mark - OPTIONAL: Deep link handler implementation
- (void)handleDeeplink:(SingularLinkParams *)params {
}
@end
インストールの確認
飛行前のチェックリスト
統合を構築してテストする前に、以下の項目を確認してください。
- CocoaPods、SPM、または手動フレームワーク経由でSDKがインストールされていること。
- Swiftブリッジングヘッダーが作成されている(Swiftを使用している場合)
-
getConfig()関数を実装 -
Singular.start(config)すべてのエントリポイントで呼び出される - SDKキーとSDKシークレットを設定に追加
- ATTタイムアウトの設定(ATTプロンプトを表示する場合のみ)
- ディープリンクハンドラを設定(ディープリンクを使用する場合のみ)
- エラーなしでアプリがビルドされる
次のステップ
- アプリをビルドして実行する
- コンソールでIDFVプリントステートメントを確認する
- IDFV を使用してSingular SDK コンソールでテストします。
- 1~2分以内にSDKコンソールにセッションが表示されることを確認する
オプションアプリ追跡の透明性(ATT)
ATTを設定して、IDFAアクセスに対するユーザー許可を要求し、帰属精度を向上させます。
以下の場合は、このセクションをスキップしてください:アプリにATTプロンプトを表示していない場合。
ATT同意を要求する理由
IDFAの利点
iOS 14.5以降、アプリはデバイスのIDFA(広告主識別子)にアクセスするためのユーザー許可を要求する必要があります。
IDFAを使用する場合と使用しない場合のアトリビューション:
- IDFAあり:正確なデバイスレベルの帰属と正確なインストール照合
- IDFAなし:IP、ユーザーエージェント、デバイスのフィンガープリントを使用した確率的帰属
推奨:より良い帰属精度のためにATTの同意を求める。IDFAなしでもSingularの帰属は可能だが、精度は低下する。
ATT遅延の設定
遅延SDK初期化
最初のセッションをSingularに送信する前に、ユーザーのATT応答を待つタイムアウトを追加します。
Critical:SDKは最初のセッションを送信する前にATTの同意を待たなければなりません。そうしないと、最初のアトリビューションイベントにIDFAが含まれません。
func getSingularConfig() -> SingularConfig? {
guard let config = SingularConfig(
apiKey: "YOUR_SDK_KEY",
andSecret: "YOUR_SDK_SECRET"
) else {
return nil
}
// Wait up to 300 seconds for ATT response
config.waitForTrackingAuthorizationWithTimeoutInterval = 300
return config
}
- (SingularConfig *)getSingularConfig {
SingularConfig *config = [[SingularConfig alloc]
initWithApiKey:@"YOUR_SDK_KEY"
andSecret:@"YOUR_SDK_SECRET"];
// Wait up to 300 seconds for ATT response
config.waitForTrackingAuthorizationWithTimeoutInterval = 300;
return config;
}
ATTフローのタイムライン
ATTディレイを設定すると、以下のようになる:
- アプリの起動:SDKがイベントの記録を開始するが、まだイベントは送信されない。
- ATTプロンプト:アプリがATT同意ダイアログを表示
- ユーザー応答:ユーザーが許可または拒否
- SDKはデータを送信します:SDKは直ちにIDFAでキューに入ったイベントを送信します(許可された場合)。
- タイムアウト・フォールバック:応答なしで300秒経過した場合、SDKはデータを送信します。
ベストプラクティスアトリビューションのためにIDFAを最大限に活用するために、できるだけ早い段階で(理想的には最初のアプリ起動時に)ATTプロンプトを表示しましょう。