どのようにお手伝いできますか?

iOS SDK V6とプラグインへの更新

  • 更新

既存のAppsFlyer iOS SDK、または他の開発環境向けの連携用ライブラリを使用した実装を、iOS SDK V6に更新します。

iOS SDK V6の概要

この記事では、SDK V6について説明します。

AppsFlyer iOS SDK V6は、次の機能を提供します。

  • アプリの所有者と開発者が、iOS 14のリリースに備えられるようにします。
  • IDFAの取得について、ユーザーに許可を求められます。
  • iOSモバイルアプリに、アプリのアトリビューションとイベントの報告機能を提供します。
  • 以前のバージョンから、APIメソッドに大幅な変更が加えられています。 0>

SDK V6の詳細や、AppsFlyer SDKをまだ使用していない新しいアプリへの実装方法は、マーケター向けiOS SDK実装ガイドを参照してください。

iOS SDK V6への更新

iOS SDK V6に更新するには、以下の手順1~5を実行します。

SDKバージョンの更新

SDK V6をダウンロードし、Xcodeに追加します。

SDK V6の実装

SDKの初期化処理に、以下のコードを追加します。

Objective-C

AppDelegate.hに、以下のコードを追加します。

#import "AppDelegate.h"
#import <0>
#import <1>
#import <2>
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // 1 - Get AppsFlyer preferences from .plist file
    NSString *path = [[NSBundle mainBundle] pathForResource:@"afdevkey_donotpush" ofType:@".plist"];
    NSDictionary* properties = [NSDictionary dictionaryWithContentsOfFile:path];
    if (properties == nil || path == nil) {
        [NSException raise:@"Error" format:@"Cannot find .plist file"];
    }
    NSString* appsFlyerDevKey = [properties objectForKey:@"appsFlyerDevKey"];
    NSString* appleAppID = [properties objectForKey:@"appleAppID"];
    if (appsFlyerDevKey == nil || appleAppID == nil) {
        [NSException raise:@"Error" format:@"Cannot find appsFlyerDevKey or appleAppID"];
    }
    // 2 - Replace 'appsFlyerDevKey', `appleAppID` with your DevKey, Apple App ID
    [[AppsFlyerLib shared] setAppsFlyerDevKey:appsFlyerDevKey];
    [[AppsFlyerLib shared] setAppleAppID:appleAppID];
    [AppsFlyerLib shared].delegate = self;
    //  Set isDebug to true to see AppsFlyer debug logs
    [AppsFlyerLib shared].isDebug = true;

    if (@available(iOS 10, *)) {
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes: UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
    return YES;
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    [[AppsFlyerLib shared] start];
}

// Deep linking
// Open URI-scheme for iOS 9 and above
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary *) options {
    [[AppsFlyerLib shared] handleOpenUrl:url options:options];
    return YES;
}
// Open URI-scheme for iOS 8 and below
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString*)sourceApplication annotation:(id)annotation {
    [[AppsFlyerLib shared] handleOpenURL:url sourceApplication:sourceApplication withAnnotation:annotation];
    return YES;
}
// Open Universal Links
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler {
    [[AppsFlyerLib shared] continueUserActivity:userActivity restorationHandler:restorationHandler];
    return YES;
}
// Report Push Notification attribution data for re-engagements
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    [[AppsFlyerLib shared] handlePushNotification:userInfo];
}
// AppsFlyerLib implementation
//Handle Conversion Data (Deferred Deep Link)
-(void)onConversionDataSuccess:(NSDictionary*) installData {
    id status = [installData objectForKey:@"af_status"];
    if([status isEqualToString:@"Non-organic"]) {
        id sourceID = [installData objectForKey:@"media_source"];
        id campaign = [installData objectForKey:@"campaign"];
        NSLog(@"This is a none organic install. Media source: %@  Campaign: %@",sourceID,campaign);
    } else if([status isEqualToString:@"Organic"]) {
        NSLog(@"This is an organic install.");
    }
}
-(void)onConversionDataFail:(NSError *) error {
    NSLog(@"%@",error);
}
//Handle Direct Deep Link
- (void) onAppOpenAttribution:(NSDictionary*) attributionData {
    NSLog(@"%@",attributionData);
}
- (void) onAppOpenAttributionFailure:(NSError *)error {
    NSLog(@"%@",error);
}
// support for scene delegate
#pragma mark - UISceneSession lifecycle
- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options API_AVAILABLE(ios(13)){
    // Called when a new scene session is being created.
    // Use this method to select a configuration to create the new scene with.
    return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
}
- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet *)sceneSessions  API_AVAILABLE(ios(13.0)){
    // Called when the user discards a scene session.
    // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
    // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
@end
Swift

AppDelegate.swiftに、以下のコードを追加します。

import UIKit
import AppTrackingTransparency
import AppsFlyerLib
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // 1 - Get AppsFlyer preferences from .plist file
        guard let propertiesPath = Bundle.main.path(forResource: "afdevkey_donotpush", ofType: "plist"),
            let properties = NSDictionary(contentsOfFile: propertiesPath) as? [String:String] else {
                fatalError("Cannot find `afdevkey_donotpush`")
        }
        guard let appsFlyerDevKey = properties["appsFlyerDevKey"],
                   let appleAppID = properties["appleAppID"] else {
            fatalError("Cannot find `appsFlyerDevKey` or `appleAppID` key")
        }
        // 2 - Replace 'appsFlyerDevKey', `appleAppID` with your DevKey, Apple App ID
        AppsFlyerLib.shared().appsFlyerDevKey = appsFlyerDevKey
        AppsFlyerLib.shared().appleAppID = appleAppID
        AppsFlyerLib.shared().delegate = self
        //  Set isDebug to true to see AppsFlyer debug logs
        AppsFlyerLib.shared().isDebug = true

        // iOS 10 or later
        if #available(iOS 10, *) {
            UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .alert, .sound]) { _, _ in }
            application.registerForRemoteNotifications()
        }
        // iOS 9 support - Given for reference. This demo app supports iOS 13 and above
        else {
            UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil))
            UIApplication.shared.registerForRemoteNotifications()
        }
        return true
    }
    func applicationDidBecomeActive(_ application: UIApplication) {
        // Start the SDK (start the IDFA timeout set above, for iOS 14 or later)
        AppsFlyerLib.shared().start()
    }
    // Open Univerasal Links
    // For Swift version < 4.2 replace function signature with the commented out code
    // func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool { // this line for Swift < 4.2
    func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
        AppsFlyerLib.shared().continue(userActivity, restorationHandler: nil)
        return true
    }
    // Open Deeplinks
    // Open URI-scheme for iOS 8 and below
    func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
        AppsFlyerLib.shared().handleOpen(url, sourceApplication: sourceApplication, withAnnotation: annotation)
        return true
    }
    // Open URI-scheme for iOS 9 and above
    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        AppsFlyerLib.shared().handleOpen(url, options: options)
        return true
    }
    // Report Push Notification attribution data for re-engagements
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        AppsFlyerLib.shared().handlePushNotification(userInfo)
    }
}
extension AppDelegate: AppsFlyerLibDelegate {
    // Handle Organic/Non-organic installation
    func onConversionDataSuccess(_ data: [AnyHashable: Any]) {
        print("onConversionDataSuccess data:")
        for (key, value) in data {
            print(key, ":", value)
        }
        if let status = data["af_status"] as? String {
            if (status == "Non-organic") {
                if let sourceID = data["media_source"],
                    let campaign = data["campaign"] {
                    print("This is a Non-Organic install. Media source: \(sourceID)  Campaign: \(campaign)")
                }
            } else {
                print("This is an organic install.")
            }
            if let is_first_launch = data["is_first_launch"] as? Bool,
                is_first_launch {
                print("First Launch")
            } else {
                print("Not First Launch")
            }
        }
    }
    func onConversionDataFail(_ error: Error) {
        print("\(error)")
    }
    // Handle Deeplink
    func onAppOpenAttribution(_ attributionData: [AnyHashable: Any]) {
        //Handle Deep Link Data
        print("onAppOpenAttribution data:")
        for (key, value) in attributionData {
            print(key, ":",value)
        }
    }
    func onAppOpenAttributionFailure(_ error: Error) {
        print("\(error)")
    }
}
SKAdNetworkのアトリビューションへの対応

SKAdNetworkは、広告によるアプリのインストールを検証するために、iOSが使用するクラスです。アプリのインストール検証には、広告を表示するアプリと、広告の対象となるアプリの両方が関わります。 0>

広告を表示するアプリは、アドネットワークが署名した広告を表示して、広告キャンペーンに参加します。アプリに広告を表示するための設定は、AppsFlyer SDKの対応範囲外です。設定するには、iOSの手順に従ってください。

広告の対象となるアプリについては、AppsFlyerのSKAdNetworkソリューションがSKAdNetworkを利用して、ユーザーのプライバシーを保護しながら、広告主やアドネットワークにLTV分析、レポート、ポストバックを提供します。アプリの初回起動時に、AppsFlyerプラットフォームはマーケターが設定した内容に基づき、SKAdNetworkのコンバージョン値の設定方法をSDKに指示します。

AppsFlyerのSKAdNetworkソリューションを利用する場合:

  • 開発者による作業は不要です。
  • AppsFlyer SDKが自動的に、必要なSKAdNetwork APIであるregisterAppForAdNetworkAttribution()とupdateConversionValue()を呼び出します。開発者がこれらのAPIを呼び出してはいけません。 0>
  • 他のSDKがSKAdNetwork APIを呼び出さないようにしてください。他のSDKが呼び出すと、iOSからAppsFlyerへのポストバック送信が遅れたり、コンバージョン値が変更されたりする可能性があります。AppsFlyerはこのコンバージョン値を使い、マーケターがダッシュボードで設定した内容に基づいて、ユーザーの質を示す計測データをSKAdNetworkダッシュボードに表示します。
  • マーケターは、AppsFlyerでSKAdNetworkの計測を設定する必要があります。 0>

開発者、マーケターともに、App Storeで追加の操作や登録を行う必要はありません。

APIの変更

AppsFlyer iOS SDK V6では、一部のAPI名が変更されています。以下の表を参照し、以前のSDKバージョンのAPI名を現在の名称に変更してください。

API名(V6より前) 現在のAPI名(V6以降)
AppsFlyerTracker AppsFlyerLib
disableIAdTracking disableCollectASA
trackAppLaunchWithCompletionHandler

startWithCompletionHandler

trackLocation

logLocation

trackAppLaunch

start

trackEvent

logEvent

disableAppleAdSupportTracking

disableAdvertisingIdentifier

validateAndTrackInAppPurchase

validateAndLogInAppPurchase

isStopTracking

isStopped

deviceTrackingDisabled/deviceLoggingDisabled

anonymizeUser

sharedTracker (Objective C) shared
プッシュ通知の実装確認

すでにプッシュ通知を実装している場合は、次の対応が必要です。

プッシュ通知の手順に従い、handlePushNotificationDataメソッドを使って、プッシュ通知が実装されていることを確認してください。

プラグイン

次のV6プラグインを利用できます。

Unity

AppsFlyerのUnity V6プラグインは、アプリの所有者と開発者によるiOS 14への対応を支援し、Unityで開発したAndroidとiOSのモバイルアプリに、アプリのアトリビューションとイベントの報告機能を提供します。このプラグインの機能は、AppsFlyerのiOS SDKおよびAndroid SDKと同等です。

以前のバージョンから更新する場合は、UnityプラグインV6への更新ガイドを参照してください。

React Native

AppsFlyerのReact Nativeプラグインは、アプリの所有者と開発者によるiOS 14への対応を支援し、AndroidとiOSのモバイルアプリに、アプリのアトリビューションとイベントの報告機能を提供します。このプラグインの機能は、AppsFlyerのiOS SDKおよびAndroid SDKと同等です。

以前のバージョンから更新する方法:

  1. 旧プラグインを削除し、GitHubのガイドに従って置き換えます。 0>
  2. 必要なAPIの名称変更と削除を行い、実装コードを変更します。
Segment

AppsFlyerのSegmentプラグインは、アプリの所有者と開発者によるiOS 14への対応を支援し、AndroidとiOSのモバイルアプリに、アプリのアトリビューションとイベントの報告機能を提供します。このプラグインの機能は、AppsFlyerのiOS SDKおよびAndroid SDKと同等です。

以前のバージョンから更新する場合は、旧プラグインを削除し、GitHubのガイドに従って置き換えます。

Cordova

AppsFlyerのCordovaプラグインは、アプリの所有者と開発者によるiOS 14への対応を支援し、AndroidとiOSのモバイルアプリに、アプリのアトリビューションとイベントの報告機能を提供します。このプラグインの機能は、AppsFlyerのiOS SDKおよびAndroid SDKと同等です。

以前のバージョンから更新する場合は、旧プラグインを削除し、GitHubのガイドに従って置き換えます。

Flutter

AppsFlyerのFlutterプラグインは、アプリの所有者と開発者によるiOS 14への対応を支援し、AndroidとiOSのモバイルアプリに、アプリのアトリビューションとイベントの報告機能を提供します。このプラグインの機能は、AppsFlyerのiOS SDKおよびAndroid SDKと同等です。

以前のバージョンから更新する場合は、旧プラグインを削除し、pubspec.yamlにV6バージョンを追加します。pub.devのガイドに従ってください。

Adobe AIR

AppsFlyerのAdobe AIRプラグインは、アプリの所有者と開発者によるiOS 14への対応を支援し、AndroidとiOSのモバイルアプリに、アプリのアトリビューションとイベントの報告機能を提供します。このプラグインの機能は、AppsFlyerのiOS SDKおよびAndroid SDKと同等です。

以前のバージョンから更新する場合は、旧プラグインを削除し、GitHubのガイドに従って置き換えます。