En resumen: Actualiza una integración existente del SDK/wrapper de AppsFlyer para iOS al SDK V6 para iOS.
Acerca del SDK V6 para iOS
Referencia en este artículo al SDK V6.
El SDK V6 de AppsFlyer para iOS:
- Permite a los propietarios y desarrolladores de aplicaciones prepararse para el lanzamiento de iOS 14.
- Te da la opción de pedir permiso a los usuarios para recopilar el IDFA.
- Proporciona funcionalidad de atribución de aplicaciones y reporte de eventos a las aplicaciones móviles de iOS.
- Incluye cambios significativos en el método de API con respecto a versiones anteriores.
Para obtener información completa sobre el SDK V6 e integrarlo en una nueva aplicación que no tenga una versión anterior del SDK de AppsFlyer, lee nuestra guía de integración del SDK para iOS para marketers.
Actualización al SDK V6 para iOS
Para actualizar al SDK V6 para iOS, completa los pasos (1-5) que se indican a continuación.
1. Actualizar la versión del SDK
Descarga y agrega el SDK V6 a tu Xcode.
2. Implementar el SDK V6
Agrega el siguiente código a la inicialización del SDK:
En AppDelegate.h, haz lo siguiente:
#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
En AppDelegate.swift, agrega lo siguiente:
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. Soporte de la atribución de SKAdNetwork
SKAdNetwork es una clase usada por iOS que valida las instalaciones de aplicaciones impulsadas por los anunciantes. El proceso de validación de la instalación de la aplicación implica la aplicación fuente y la aplicación anunciada.
Una aplicación fuente es una aplicación que participa en campañas publicitarias mostrando los anuncios firmados por una red de publicidad. La configuración de tu aplicación para mostrar anuncios no está dentro del alcance del SDK de AppsFlyer. Para configurarla, debes seguir las instrucciones de iOS.
Para configurar la aplicación anunciada, la Solución SKAdNetwork de AppsFlyer utiliza SKAdNetwork para proporcionar a los anunciantes y a las redes de publicidad análisis, reportes y postbacks de LTV, al tiempo que se mantiene la privacidad del usuario. Al iniciar la aplicación por primera vez, la plataforma AppsFlyer, utilizando la configuración establecida por el marketer, le indica al SDK cómo establecer el valor de conversión de SKAdNetwork.
Para usar la Solución SKAdNetwork:
- El desarrollador no hace nada.
-
El SDK de AppsFlyer llama automáticamente a las API necesarias de SKAdNetwork, es decir
registerAppForAdNetworkAttribution()
yupdateConversionValue()
. El desarrollador no debe llamarlas. - No permitas que otros SDK llamen a las API de SKAdNet. Si así lo hacen, es posible que se retrase en el envío del postback por parte de iOS a AppsFlyer y que cambie el valor de conversión que usamos para completar el panel de control de SKAdNetwork con datos de medición de la calidad del usuario según lo configurado por el marketer en el panel de control.
- El marketer debe configurar la medición de SKAdNetwork en AppsFlyer.
No se requiere ninguna otra acción o proceso de registro por parte del desarrollador o del marketer en el App Store.
4. Cambiar las API
El SDK V6 de AppsFlyer para iOS tiene algunos cambios en el nombre de la API. Consulta la siguiente tabla para cambiar los nombres de API de las versiones anteriores del SDK a los nombres actuales.
Nombre de la API (antes de V6) | Nombre de la API actual (V6 y posteriores) |
---|---|
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 |
5. Garantizar la integración de notificaciones push
Lo siguiente es necesario si la integración de notificaciones push ya está implementada.
Sigue las instrucciones de notificación push para asegurarte de que tienes las notificaciones push integradas mediante el método handlePushNotificationData.
Plugins
Están disponibles los siguientes plugins V6:
Unity
El plugin de Unity V6 de AppsFlyer ayuda a los propietarios y desarrolladores de aplicaciones a dar soporte a iOS 14, proporcionando funcionalidad de atribución de aplicaciones y reporte de eventos a las aplicaciones móviles de Android e iOS desarrolladas en la plataforma Unity. El plugin es funcionalmente equivalente a los SDK de AppsFlyer para iOS y Android.
Para actualizar tu plugin desde una versión anterior, consulta nuestras guías sobre la actualización al plugin de Unity V6:
- Desde el plugin de Unity V4 (requiere la eliminación del plugin anterior)
- Desde el plugin de Unity V5 (requiere una actualización del paquete de Unity)
React Native
El plugin de React Native de AppsFlyer ayuda a los propietarios y desarrolladores de aplicaciones a prepararse para iOS 14, proporcionando funcionalidad de atribución de aplicaciones y reporte de eventos a las aplicaciones móviles de Android e iOS. El plugin es funcionalmente equivalente a los SDK de AppsFlyer para iOS y Android.
Para actualizar tu plugin desde una versión anterior:
- Elimina el plugin anterior y reemplázalo siguiendo las instrucciones de nuestra guía de GitHub.
- Cambia el código de integración renombrando y eliminando las API necesarias.
Segment
El plugin de Segment de AppsFlyer ayuda a los propietarios y desarrolladores de aplicaciones a prepararse para iOS 14, proporcionando funcionalidad de atribución de aplicaciones y reporte de eventos a las aplicaciones móviles de Android e iOS. El plugin es funcionalmente equivalente a los SDK de AppsFlyer para iOS y Android.
Para actualizar tu plugin desde una versión anterior, elimina el plugin anterior y reemplázalo siguiendo las instrucciones de nuestra guía de GitHub.
Cordova
El plugin de Cordova de AppsFlyer ayuda a los propietarios y desarrolladores de aplicaciones a prepararse para iOS 14, proporcionando funcionalidad de atribución de aplicaciones y reporte de eventos a las aplicaciones móviles de Android e iOS. El plugin es funcionalmente equivalente a los SDK de AppsFlyer para iOS y Android.
Para actualizar tu plugin desde una versión anterior, elimina el plugin anterior y reemplázalo siguiendo las instrucciones de nuestra guía de GitHub.
Flutter
El plugin de Flutter de AppsFlyer ayuda a los propietarios y desarrolladores de aplicaciones a prepararse para iOS 14, proporcionando funcionalidad de atribución de aplicaciones y reporte de eventos a las aplicaciones móviles de Android e iOS. El plugin es funcionalmente equivalente a los SDK de AppsFlyer para iOS y Android.
Para actualizar tu plugin desde una versión anterior, elimina el plugin anterior y agrega la versión V6 a pubspec.yaml
, siguiendo las instrucciones de nuestra guía de pub.dev.
Adobe AIR
El plugin de Adobe AIR de AppsFlyer ayuda a los propietarios y desarrolladores de aplicaciones a prepararse para iOS 14, proporcionando funcionalidad de atribución de aplicaciones y reporte de eventos a las aplicaciones móviles de Android e iOS. El plugin es funcionalmente equivalente a los SDK de AppsFlyer para iOS y Android.
Para actualizar tu plugin desde una versión anterior, elimina el plugin anterior y reemplázalo siguiendo las instrucciones de nuestra guía de GitHub.