At a glance: Update an existing AppsFlyer iOS SDK/wrapper integration to iOS SDK V6.
关于iOS SDK V6
Reference in this article to SDK V6.
The AppsFlyer iOS SDK V6:
- Allows app owners and developers to prepare for iOS 14 release.
- Give you the option to ask users for permission to collect IDFA.
- 为iOS移动应用提供应用归因和事件报告功能。
- 包括对以前版本的API方法的重大更改。
For full information about the SDK V6, and to integrate it into a new app that does not have an earlier version of the AppsFlyer SDK, read our iOS SDK integration guide for marketers.
升级至iOS SDK V6
要迁移到iOS SDK V6,请完成以下步骤(1-5)。
1.更新SDK版本
Download and add the SDK V6 to your Xcode.
2.实施SDK V6
Add the following code to the SDK initialization:
在 AppDelegate.h 中:请做如下操作:
#import "AppDelegate.h"
#import <AppsFlyerLib/AppsFlyerLib.h>
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#import <UserNotifications/UserNotifications.h>
@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
在 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)")
}
}
3. Support for SKAdNetwork attribution
SKAdNetwork是iOS使用的一个类(class),用于验证广告推广所获取的新增用户的激活(install)数据。整个应用激活的验证流程涉及流量方应用和广告主应用。
A source app is an app that participates in ad campaigns by displaying ads signed by an ad network. Configuring your app to display ads is not within the scope of the AppsFlyer SDK. To configure, you must follow the iOS instructions.
For configuring the advertised app, the AppsFlyer SKAdNetwork Solution uses the SKAdNetwork to provide advertisers and ad networks with LTV analytics, reports, and postbacks, while maintaining user privacy. On launching the app for the first time, the AppsFlyer platform, using the configuration set by the marketer, instructs the SDK how to set the SKAdNetwork conversion value.
- 开发人员无需操作。
-
AppsFlyer SDK会自动调用必要的SKAdNetwork API,即
registerAppForAdNetworkAttribution()
和updateConversionValue()
。开发人员请勿再单独调用。 - Don't allow other SDKs to call SKAdNet APIs. Doing so can delay iOS in sending the postback to AppsFlyer and change the conversion value which we use to populate the SKAdNetwork dashboard with user quality measurement data as configured by the marketer in the dashboard.
- 广告主需要在其AppsFlyer面板配置SKAdNetwork功能
开发人员和市场人员都无需在应用商店中再进行其他操作或注册流程。
4.更改APIs
The AppsFlyer iOS SDK V6 has some API name changes. See the following table to change the API names from the earlier SDK versions to the current names.
API名称(在V6之前) | 当前的API名称(V6和更高版本) |
---|---|
AppsFlyerTracker | AppsFlyerLib |
disableIAdTracking | disableCollectASA |
trackAppLaunchWithCompletionHandler |
startWithCompletionHandler |
trackLocation |
logLocation |
trackAppLaunch |
开始 |
trackEvent |
logEvent |
disableAppleAdSupportTracking |
disableAdvertisingIdentifier |
validateAndTrackInAppPurchase |
validateAndLogInAppPurchase |
isStopTracking |
isStopped |
deviceTrackingDisabled/deviceLoggingDisabled |
anonymizeUser |
sharedTracker (Objective C) | shared |
5.确保推送通知集成
如果集成了推送通知(push notification)功能,还需要完成以下步骤。
Follow the push notification instructions to ensure you have push notifications integrated using the handlePushNotificationData method.
插件
The following V6 plugins are available:
Unity
AppsFlyer Unity V6插件(beta)可帮助应用所有者和开发人员为iOS 14做准备,为在Unity开发平台上开发的Android和iOS移动应用提供应用归因和事件报告功能。该插件在功能上等同于AppsFlyer iOS和Android SDK。
要更新老版本插件,请参阅有关迁移到Unity插件V6 beta的指南:
- From Unity plugin V4 (requires removal of the old plugin)
- From Unity plugin V5 (requires an update of the Unity package)
React Native
The AppsFlyer React Native plugin helps app owners and developers prepare for iOS 14, providing app attribution and event reporting functionality to Android and iOS mobile apps. The plugin is functionally equivalent to the AppsFlyer iOS and Android SDKs.
要从早期版本更新插件:
- 删除早期的插件,并按照我们在 GitHub指南 的说明进行替换。
- 通过 重命名和删除 必要的API来更改集成代码。
Segment
The AppsFlyer Segment plugin helps app owners and developers prepare for iOS 14, providing app attribution and event reporting functionality to Android and iOS mobile apps. The plugin is functionally equivalent to the AppsFlyer iOS and Android SDKs.
要从较早的版本更新您的插件,请 移除较早的插件并按照我们的 GitHub指南 的说明进行替换。
Cordova
The AppsFlyer Cordova plugin helps app owners and developers prepare for iOS 14, providing app attribution and event reporting functionality to Android and iOS mobile apps. The plugin is functionally equivalent to the AppsFlyer iOS and Android SDKs.
要从较早的版本更新您的插件,请 移除较早的插件并按照我们的 GitHub指南 的说明进行替换。
Flutter
The AppsFlyer Flutter plugin helps app owners and developers prepare for iOS 14, providing app attribution and event reporting functionality to Android and iOS mobile apps. The plugin is functionally equivalent to the AppsFlyer iOS and Android SDKs.
如果是从老版本的插件更新,请删除靠版本插件,然后将V6版本添加到pubspec.yaml
,请按照pub.dev指南中的说明进行操作。
Adobe AIR
The AppsFlyer Adobe AIR plugin helps app owners and developers prepare for iOS 14, providing app attribution and event reporting functionality to Android and iOS mobile apps. The plugin is functionally equivalent to the AppsFlyer iOS and Android SDKs.
要从较早的版本更新您的插件,请 移除较早的插件并按照我们的 GitHub指南 的说明进行替换。