🛠 为了让我们提供最佳支持,我们诚挚地请求您将任何问题提交到以下邮箱:[email protected]
提交问题时,请具体说明您的AppsFlyer注册(账户)电子邮件、应用ID、生产步骤、记录、代码片段和任何其他相关信息。
- 从版本
6.3.2
开始,我们使用xcframework
为iOS平台,然后您需要使用版本 >= 1.10 的CocoaPods。
要安装segment-appsflyer-ios集成
- 只需将以下行添加到您的CocoaPods
Podfile
中
生产版本
pod 'segment-appsflyer-ios', '6.14.4'
严格模式SDK版本
pod 'segment-appsflyer-ios/Strict', '6.14.4'
使用严格模式SDK可以完全删除IDFA收集功能以及AdSupport框架依赖(例如,当开发针对儿童的应用程序时)。
- 在项目目录中运行
pod install
在XCode中,转到文件 > Swift包 > 添加包依赖... 并将https://github.com/AppsFlyerSDK/segment-appsflyer-ios添加为包依赖URL。
从版本6.8.0
开始,我们支持手动模式以分离AppsFlyer SDK的初始化和启动。在这种情况下,AppsFlyer SDK不会自动启动,这样当开发人员决定何时启动AppsFlyer SDK时会更有自由度。请注意,在手动模式下,开发人员需要实现API AppsFlyerLib.shared().start()
以启动SDK。
如果您正在使用CMP收集同意数据,则需要此功能。请参阅此处的解释。
SEGAppsFlyerIntegrationFactory* factoryWithManualMode = [SEGAppsFlyerIntegrationFactory createWithManualMode:YES];
let factoryWithManualMode = SEGAppsFlyerIntegrationFactory.create(withManualMode: true);
请查看以下示例,了解如何使用委托与手动模式一起使用。
要启动AppsFlyer SDK,使用以下start()
API
[[AppsFlyerLib shared] start];
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue: nil usingBlock:^(NSNotification * _Nonnull note) {
[[AppsFlyerLib shared] start];
}];
AppsFlyerLib.shared().start()
NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: nil) { Notification in
AppsFlyerLib.shared().start()
}
注意 - 通过addObserver
调用确保每次应用程序的启动(从后台到前台)都被正确记录。
请参阅更详细的说明此处
首先,您必须在Segment的仪表板中为AppsFlyer集成提供AppsFlyer Dev Key、Apple App ID(iTunes)和客户端密钥的值
打开AppDelegate.h
并添加
#import "SEGAppsFlyerIntegrationFactory.h"
AppDelegate.m
中➜didFinishLaunchingWithOptions
// For ApsFlyer debug logs
[AppsFlyerLib shared].isDebug = YES;
// [[AppsFlyerLib shared] waitForATTUserAuthorizationWithTimeoutInterval:60];
/*
Based on your needs you can either pass a delegate to process deferred
and direct deeplinking callbacks or disregard them.
If you choose to use the delegate, see extension to this class below
*/
SEGAppsFlyerIntegrationFactory* factoryNoDelegate = [SEGAppsFlyerIntegrationFactory instance];
// SEGAppsFlyerIntegrationFactory* factoryWithDelegate = [SEGAppsFlyerIntegrationFactory createWithLaunchDelegate:self];
// To use the manual mode, use the following method
// SEGAppsFlyerIntegrationFactory* factoryNoDelegate = [SEGAppsFlyerIntegrationFactory createWithManualMode:YES];
// SEGAppsFlyerIntegrationFactory* factoryWithDelegate = [SEGAppsFlyerIntegrationFactory createWithLaunchDelegate:self andManualMode:YES];
SEGAnalyticsConfiguration *config = [SEGAnalyticsConfiguration configurationWithWriteKey:@"SEGMENT_KEY"];
[config use:factoryNoDelegate];
// [config use:factoryWithDelegate]; // use this if you want to get conversion data in the app. Read more in the integration guide
config.enableAdvertisingTracking = YES; //OPTIONAL
config.trackApplicationLifecycleEvents = YES; //OPTIONAL
config.trackDeepLinks = YES; //OPTIONAL
config.trackPushNotifications = YES; //OPTIONAL
[SEGAnalytics debug:YES]; //OPTIONAL
[SEGAnalytics setupWithConfiguration:config];
AppDelegate.m
中➜applicationDidBecomeActive
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Getting user consent dialog. Please read https://dev.appsflyer.com/hc/docs/integrate-ios-sdk#enabling-app-tracking-transparency-att-support
if (@available(iOS 14, *)) {
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
//....
}];
}
}
- 打开/创建
<Your-App-name>-Bridging-Header.h
并添加
#import "SEGAppsFlyerIntegrationFactory.h"
-
在构建设置 > Swift编译器 - 一般 > Objective-C桥接头中添加路径
-
打开
AppDelegate.swift
并添加
import Segment
import AppsFlyerLib
import segment_appsflyer_ios
- 在
didFinishLaunchingWithOptions
中添加
// For AppsFLyer debug logs uncomment the line below
// AppsFlyerLib.shared().isDebug = true
// AppsFlyerLib.shared().waitForATTUserAuthorization(withTimeoutInterval: 60)
/*
Based on your needs you can either pass a delegate to process deferred
and direct deeplinking callbacks or disregard them.
If you choose to use the delegate, see extension to this class below
*/
// let factoryWithDelegate : SEGAppsFlyerIntegrationFactory = SEGAppsFlyerIntegrationFactory.create(withLaunch: self)
let factoryNoDelegate = SEGAppsFlyerIntegrationFactory()
/* If you want to use the manual mode, please use the following methods
with or without delegate */
// let factoryWithDelegate : SEGAppsFlyerIntegrationFactory = SEGAppsFlyerIntegrationFactory.create(withLaunch: self, andManualMode:true)
// let factoryNoDelegate = SEGAppsFlyerIntegrationFactory.create(withManualMode: true)
// Segment initialization
let config = AnalyticsConfiguration(writeKey: "SEGMENT_KEY")
// config.use(factoryWithDelegate) // use this if you want to get conversion data in the app. Read more in the integration guide
config.use(factoryNoDelegate)
config.enableAdvertisingTracking = true //OPTIONAL
config.trackApplicationLifecycleEvents = true //OPTIONAL
config.trackDeepLinks = true //OPTIONAL
config.trackPushNotifications = true //OPTIONAL
Analytics.debug(false)
Analytics.setup(with: config)
在 applicationDidBecomeActive
中添加
func applicationDidBecomeActive(_ application: UIApplication) {
// If you want to collect IDFA, please add the code below and read https://support.appsflyer.com//hc/en-us/articles/207032066#integration-35-support-apptrackingtransparency-att
if #available(iOS 14, *) {
ATTrackingManager.requestTrackingAuthorization(completionHandler: { (status) in
// ...
})
}
}
AppsFlyer集成响应identify
调用。欲了解更多信息,请访问Segment identify方法文档。在identify调用中,在traits
字典中设置setCustomerUserID
和currencyCode
为了将转换数据发送到Segment,请确保您已启用“追踪归因数据”并在AppsFlyer目标设置中指定App ID
为了获取转换数据,您需要
- 将
SEGAppsFlyerLibDelegate
协议添加到您的AppDelegate.h(或其他)类
#import <UIKit/UIKit.h>
#import "SEGAppsFlyerIntegrationFactory.h"
@interface AppDelegate : UIResponder <UIApplicationDelegate, SEGAppsFlyerLibDelegate>
- 配置Segment Analytics时传递AppDelegate(或其他)类。将行
[config use:[SEGAppsFlyerIntegrationFactory instance]];
更改为[config use:[SEGAppsFlyerIntegrationFactory createWithLaunchDelegate:self]];
- 在上面的方法传回的类中(默认为AppDelegate.m)实现
SEGAppsFlyerLibDelegate
协议的方法。请参见以下示例代码
#import "AppDelegate.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
-(void)onConversionDataSuccess:(NSDictionary*) installData {
BOOL first_launch_flag = [[installData objectForKey:@"is_first_launch"] boolValue];
NSString *status = [installData objectForKey:@"af_status"];
if(first_launch_flag) {
if ([status isEqualToString:@"Non-organic"]){
NSString *sourceID = [installData objectForKey:@"media_source"];
NSString *campaign = [installData objectForKey:@"campaign"];
NSLog(@"This is a non-organic install. Media source: %@ Campaign: %@", sourceID, campaign);
} else {
NSLog(@"This is an organic install");
}
} else {
NSLog(@"Not first launch");
}
};
/**
Any errors that occurred during the conversion request.
*/
-(void)onConversionDataFail:(NSError *) error {
NSLog(@"%@", [error description]);
};
/**
`attributionData` contains information about OneLink, deeplink.
*/
- (void)onAppOpenAttribution:(NSDictionary *)attributionData{
NSLog(@"onAppOpenAttribution");
for(id key in attributionData){
NSLog(@"onAppOpenAttribution: key=%@ value=%@", key, [attributionData objectForKey:key]);
}
};
/**
Any errors that occurred during the attribution request.
*/
- (void)onAppOpenAttributionFailure:(NSError *)error{
NSLog(@"%@", [error description]);
};
// Rest of your AppDelegate code
为了获取转换数据,您需要
- 将
SEGAppsFlyerLibDelegate
协议添加到您的AppDelegate(或其他)类 - 配置Segment Analytics时传递AppDelegate(或其他)类。如果使用前面的示例代码,请将行
config.use(factoryNoDelegate)
更改为config.use(factoryWithDelegate)
- 在作为代理传递的类中实现协议的方法。请参见以下示例代码,其中AppDelegate被用于此目的
class AppDelegate: UIResponder, UIApplicationDelegate, SEGAppsFlyerLibDelegate {
var window: UIWindow?
func onConversionDataSuccess(_ conversionInfo: [AnyHashable : Any]) {
guard let first_launch_flag = conversionInfo["is_first_launch"] as? Int else {
return
}
guard let status = conversionInfo["af_status"] as? String else {
return
}
if(first_launch_flag == 1) {
if(status == "Non-organic") {
if let media_source = conversionInfo["media_source"] , let campaign = conversionInfo["campaign"]{
print("This is a Non-Organic install. Media source: \(media_source) Campaign: \(campaign)")
}
} else {
print("This is an organic install.")
}
} else {
print("Not First Launch")
}
}
func onAppOpenAttribution(_ attributionData: [AnyHashable : Any]) {
print("Deep Link Data goes here:")
if let data = attributionData{
print("\(data)")
}
}
func onConversionDataFail(_ error: Error) {
}
func onAppOpenAttributionFailure(_ error: Error?) {
}
//rest of you AppDelegate code
}
为了使用统一深度链接,您需要
- 将
SEGAppsFlyerDeepLinkDelegate
协议添加到您的AppDelegate(或其他)类 - 配置Segment Analytics时传递AppDelegate(或其他)类。从上面的示例代码中,将factroyWithDelegate更改为
let factoryWithDelegate: SEGAppsFlyerIntegrationFactory = SEGAppsFlyerIntegrationFactory.create(withLaunch: self, andDeepLinkDelegate: self)
- 在作为代理传递的类中实现协议的方法。请参见以下示例代码,其中AppDelegate被用于此目的
extension AppDelegate: SEGAppsFlyerDeepLinkDelegate {
func didResolveDeepLink(_ result: DeepLinkResult) {
print(result)
}
}
如果您正在与不允许将用户级别数据传递给第三方的网络工作,您需要在调用之前应用代码以过滤这些网络
// [self.analytics track:@"Install Attributed" properties:[properties copy]];
@import AppsFlyerLib;
...
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(integrationDidStart:) name:SEGAnalyticsIntegrationDidStart object:nil];
...
}
...
- (void)integrationDidStart:(nonnull NSNotification *)notification {
NSString *integration = notification.object;
if ([integration isEqualToString:@"AppsFlyer"]) {
/// Additional AppsFlyer SDK setup goes below
/// All setup is optional
/// To set Apple App ID and AppsFlyer Dev Key use Segment dashboard
/// ...
/// Enable ESP support for specific URLs
[[AppsFlyerLib shared] setResolveDeepLinkURLs:@[@"afsdktests.com"]];
/// Disable printing SDK messages to the console log
[[AppsFlyerLib shared] setIsDebug:NO];
/// `OneLink ID` from OneLink configuration
[[AppsFlyerLib shared] setAppInviteOneLink:@"one_link_id"];
}
}
有关DMA同意数据的通用介绍,请参阅此处。SDK提供两种用于收集同意数据的方法
- 通过同意管理平台(CMP):如果应用程序使用符合透明度和同意框架(TCF)v2.2协议的CMP,则SDK可以自动检索同意详情。
或者 - 通过专用SDK API:开发人员可以使用专为该目的设计的特定API直接将谷歌要求的同意数据传递给SDK。
兼容TCF v2.2的CMP收集DMA同意数据并将其存储在NSUserDefaults
中。为了启用SDK访问此数据并在每个事件中包含它,请按以下步骤操作
- 调用
AppsFlyerLib.shared().enableTCFDataCollection(true)
以指示SDK从设备收集TCF数据。 - 使用手动模式初始化
SEGAppsFlyerIntegrationFactory
。这将允许我们延迟转换调用,以便向SDK提供用户同意。 - 在
applicationDidBecomeActive
生命周期方法中,使用CMP决定是否需要在当前会话中显示同意对话框以获取同意数据。如果需要同意对话框,请转到第4步;否则,请转到第5步。 - 从CMP获取确认,表明用户已做出同意决定并且数据已存储在
NSUserDefaults
中。 - 调用
AppsFlyerLib.shared().start()
。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// For AppsFLyer debug logs uncomment the line below
AppsFlyerLib.shared().isDebug = true
AppsFlyerLib.shared().waitForATTUserAuthorization(timeoutInterval: 60)
AppsFlyerLib.shared().enableTCFDataCollection(true)
let factoryWithDelegateAndManual: SEGAppsFlyerIntegrationFactory =SEGAppsFlyerIntegrationFactory.create(withLaunch: self, andDeepLinkDelegate: self, andManualMode: true)
// Segment initialization
let config = AnalyticsConfiguration(writeKey: "SEGMENT_KEY")
config.use(factoryWithDelegateAndManual)
config.enableAdvertisingTracking = true //OPTIONAL
config.trackApplicationLifecycleEvents = true //OPTIONAL
config.trackDeepLinks = true //OPTIONAL
config.trackPushNotifications = true //OPTIONAL
Analytics.debug(true)
Analytics.setup(with: config)
return true
}
func applicationDidBecomeActive(_ application: UIApplication) {
if(cmpManager!.hasConsent()){
//CMP manager already has consent ready - you can start
AppsFlyerLib.shared().start()
}else{
//CMP doesn't have consent data ready yet
//Waiting for CMP completion and data ready and then start
cmpManager?.withOnCmpButtonClickedCallback({ CmpButtonEvent in
AppsFlyerLib.shared().start()
})
}
if #available(iOS 14, *) {
ATTrackingManager.requestTrackingAuthorization { (status) in
switch status {
case .denied:
print("AuthorizationSatus is denied")
case .notDetermined:
print("AuthorizationSatus is notDetermined")
case .restricted:
print("AuthorizationSatus is restricted")
case .authorized:
print("AuthorizationSatus is authorized")
@unknown default:
fatalError("Invalid authorization status")
}
}
}
}
如果您的应用程序不使用兼容TCF v2.2的CMP,请使用以下详细说明的SDK API直接将同意数据传递给SDK。
- 使用手动模式初始化
SEGAppsFlyerIntegrationFactory
。这将允许我们延迟转换调用,以便向SDK提供用户同意。 - 在
applicationDidBecomeActive
生命周期方法中确定GDPR是否适用于用户。
- 如果通用数据保护条例(GDPR)适用于用户,则执行以下操作:- 鉴于GDPR适用于用户,判断是否已存储本会话的同意数据。
- 如果没有存储同意数据,则显示同意对话框以捕获用户的同意决定。
- 如果有存储同意数据,则继续下一步。
- 要将同意数据传输到SDK,请使用以下参数创建一个AppsFlyerConsent对象:
-forGDPRUserWithHasConsentForDataUsage
- 指示用户是否同意将其数据用于广告目的。 -hasConsentForAdsPersonalization
- 指示用户是否同意将其数据用于个性化广告。 - 调用
AppsFlyerLib.shared().setConsentData(AppsFlyerConsent(forGDPRUserWithHasConsentForDataUsage: Bool, hasConsentForAdsPersonalization: Bool))
。 - 调用
AppsFlyerLib.shared().start()
。
- 如果GDPR不适用于用户,则执行以下操作:- 调用
AppsFlyerLib.shared().setConsentData(AppsFlyerConsent(nonGDPRUser: ()))
。 - 使用手动模式初始化
SEGAppsFlyerIntegrationFactory
是可选的,不再强制要求。
- 鉴于GDPR适用于用户,判断是否已存储本会话的同意数据。
该项目有4个示例,针对Objective-C和Swift(包含故障排除)。要尝试它,克隆此存储库,然后从每个示例中首先运行pod install
以安装项目依赖项。