Show Menu
TEMAS×

Integración del SDK de Campaign en la aplicación móvil

Los SDK de Campaign para iOS y Android son uno de los componentes del módulo Mobile App Channel.
Para obtener el SDK de Campaign (anteriormente denominado SDK de Neolane), póngase en contacto con el servicio de atención al cliente de Adobe.
El objetivo del SDK es facilitar la integración de una aplicación móvil en la plataforma de Adobe Campaign.
Para obtener más información sobre las diferentes versiones de iOS y Android compatibles, consulte la matriz de compatibilidad .

Cargando SDK de Campaign

  • En Android : el archivo neolane_sdk-release.aar debe estar vinculado al proyecto.
    El siguiente permiso concede acceso al servidor de Adobe Campaign:
    Neolane.getInstance().setIntegrationKey("your Adobe mobile app integration key");
    Neolane.getInstance().setMarketingHost("https://yourMarketingHost:yourMarketingPort/");
    Neolane.getInstance().setTrackingHost("https://yourTrackingHost:yourTrackingPort/");
    
    
    El siguiente permiso permite recuperar una ID única del teléfono:
    <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
    
    
    A partir de la versión 1.0.24 del SDK, este permiso solo se utiliza para versiones anteriores a Android 6.0.
    A partir de la versión 1.0.26 del SDK, este permiso ya no se utiliza.
  • En iOS : los archivos libNeolaneSDK.a y Neolane_SDK.h deben estar vinculados al proyecto. A partir de la versión 1.0.24 del SDK, la opción ENABLE_BITCODE está activada.
    Para la versión 1.0.25 del SDK, las cuatro arquitecturas están disponibles en el archivo Neolane_SDK.h .

Declarar configuraciones de integración

Para integrar el SDK de Campaign en la aplicación móvil, el administrador funcional debe proporcionar la siguiente información al desarrollador:
  • Una clave de integración : para permitir a la plataforma Adobe Campaign identificar la aplicación móvil.
    Esta clave de integración se introduce en la consola de Adobe Campaign, en la pestaña Information del servicio dedicado a la aplicación móvil. Consulte Configuración de la aplicación móvil en Adobe Campaign .
  • Una URL de seguimiento : coincide con la dirección del servidor de rastreo de Adobe Campaign.
  • Una URL de marketing : para habilitar la recopilación de suscripciones.
  • En Android :
    Neolane.getInstance().setIntegrationKey("your Adobe mobile app integration key");
    Neolane.getInstance().setMarketingHost("https://yourMarketingHost:yourMarketingPort/");
    Neolane.getInstance().setTrackingHost("https://yourTrackingHost:yourTrackingPort/"); 
    
    
  • En iOS :
    Neolane_SDK *nl = [Neolane_SDK getInstance];
    [nl setMarketingHost:strMktHost];
    [nl setTrackingHost:strTckHost];
    [nl setIntegrationKey:strIntegrationKey];
    
    

Función de registro

La función de registro le permite:
  • Enviar la ID de notificación o ID remota a Adobe Campaign (token de dispositivo en iOS e ID de registro en Android).
  • Recuperación de la clave de reconciliación o clave de usuario userKey (por ejemplo, correo electrónico o número de cuenta).
  • En Android :
    void registerInNeolane(String registrationId, String userKey, Context context)
    {
     try{
      Neolane.getInstance().registerDevice(registrationToken, userKey, null, context);
     } catch (NeolaneException e){
      //...
     } catch (IOException e){
      //...
     }
    }
    
    
    Si se utiliza FCM (Firebase Cloud Messaging), recomendamos que se utilice la función registerDevice al seleccionar la función onTokenRefresh para notificar a Adobe Campaign del cambio en el token del dispositivo móvil del usuario.
    public class NeoTripFirebaseInstanceIDService extends FirebaseInstanceIdService {
      @Override
      public void onTokenRefresh() {
        String registrationToken = FirebaseInstanceId.getInstance().getToken();
        NeolaneAsyncRunner neolaneAs = new NeolaneAsyncRunner(Neolane.getInstance());
        ...
        ...
        // Neolane Registration
        neolaneAs.registerDevice(registrationToken, userKey, additionnalParam, this, new NeolaneAsyncRunner.RequestListener() {
        public void onComplete(String e, Object state) { ... }
        public void onNeolaneException(NeolaneException e, Object state) { ... }
        public void onIOException(IOException e, Object state) { ... }
        });
        ...
        ...
      }
    }
    
    
  • En iOS :
    // Callback called on successful registration to the APNS
    - (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
    {
        // Pass the token to Adobe Campaign
        Neolane_SDK *nl = [Neolane_SDK getInstance];
        [nl registerDevice:tokenString:self.userKey:dic];
    }
    
    

Función de seguimiento

  • En Android :
    Las funciones de seguimiento permiten rastrear las activaciones de notificaciones (aperturas) y las visualizaciones de notificaciones (capturas de pantalla).
    Para rastrear la visualización de notificaciones (realizada llamando a la función notifyReceive del SDK), siga la implementación que se muestra a continuación. Tenga en cuenta que si utiliza FCM (Firebase Cloud Messaging), se recomienda utilizar la función notifyReceive cuando el sistema Android llame a la función onMessageReceived .
    package com.android.YourApplication;
    
    import android.content.Context;
    import android.content.SharedPreferences;
    import android.os.Bundle;
    import android.util.Log;
    
    import com.google.firebase.messaging.FirebaseMessagingService;
    import com.google.firebase.messaging.RemoteMessage;
    
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Map.Entry;
    
    public class YourApplicationFirebaseMessagingService extends FirebaseMessagingService {
      private static final String TAG = "MyFirebaseMsgService";
    
      @Override
      public void onMessageReceived(RemoteMessage message) {
        Log.d(TAG, "Receive message from: " + message.getFrom());
        Map<String,String> payloadData = message.getData();
        final Bundle extras = new Bundle();
        final Iterator<Entry<String, String>> iter = payloadData.entrySet().iterator();
        while(iter.hasNext())
        {
          final Entry<String, String>  entry =iter.next();
          extras.putString(entry.getKey(), entry.getValue());
        }
    
        SharedPreferences settings = this.getSharedPreferences(YourApplicationActivity.APPLICATION_PREF_NAME, Context.MODE_PRIVATE);
        String mesg = payloadData.get("_msg");
        String title = payloadData.get("title");
        String url = payloadData.get("url");
        String messageId = payloadData.get("_mId");
        String deliveryId = payloadData.get("_dId");
        YourApplicationActivity.handleNotification(this, mesg, title, url, messageId, deliveryId, extras);
      }
    }
    
    
    public static void handleNotification(Context context, String message, String title, String url, String messageId, String deliveryId, Bundle extras){
        if( message == null ) message = "No Content";
        if( title == null )   title = "No title";
        if( url == null )     url = "https://www.tripadvisor.fr";
        int iconId = R.drawable.notif_neotrip;
    
        // notify Neolane that a notification just arrived
        NeolaneAsyncRunner nas = new NeolaneAsyncRunner(Neolane.getInstance());
        nas.notifyReceive(Integer.valueOf(messageId), deliveryId, new NeolaneAsyncRunner.RequestListener() {
          public void onNeolaneException(NeolaneException arg0, Object arg1) {}
          public void onIOException(IOException arg0, Object arg1) {}
          public void onComplete(String arg0, Object arg1){}
        });
        if (yourApplication.isActivityVisible())
        {
          Log.i("INFO", "The application has the focus" );
          ...
        }
        else
        {
          // notification creation :
          NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
          Notification notification;
    
          // Activity to start :
          Intent notifIntent = new Intent(context.getApplicationContext(), NotificationActivity.class);
          notifIntent.putExtra("notificationText", message);
          notifIntent.putExtra(NotificationActivity.NOTIFICATION_URL_KEYNAME, url);
          notifIntent.putExtra("_dId", deliveryId);
          notifIntent.putExtra("_mId", messageId);
          notifIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
          PendingIntent contentIntent = PendingIntent.getActivity(context, 1, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    
          notification = new Notification.Builder(context)
                  .setContentTitle(title)
                  .setContentText(message)
                  .setSmallIcon(iconId)
                  .setContentIntent(contentIntent)
                  .build();
    
          // launch the notification :
          notification.flags |= Notification.FLAG_AUTO_CANCEL;
          notificationManager.notify(Integer.valueOf(messageId), notification);
        }
    }
    
    
    A continuación, se muestra un ejemplo de implementación para rastrear una apertura notificación (ejecutada llamando a la función notifyOpening del SDK). La clase NotificationActivity corresponde a la clase utilizada para crear el objeto notifIntent en el ejemplo anterior.
    public class NotificationActivity extends Activity {
     public static final String NOTIFICATION_URL_KEYNAME = "NotificationUrl";
     .....
     public void onCreate(Bundle savedBundle) {
      super.onCreate(savedBundle);
      setContentView(R.layout.notification_viewer);  
      .....  
      Bundle extra = getIntent().getExtras();  
      .....  
      //get the messageId and the deliveryId to do the tracking  
      String deliveryId = extra.getString("_dId");
      String messageId = extra.getString("_mId");
      if (deliveryId != null && messageId != null) {
       NeolaneAsyncRunner neolaneAs = new NeolaneAsyncRunner(Neolane.getInstance());
       neolaneAs.notifyOpening(Integer.valueOf(messageId), deliveryId, new NeolaneAsyncRunner.RequestListener() {
        public void onNeolaneException(NeolaneException arg0, Object arg1) {}
        public void onIOException(IOException arg0, Object arg1) {}
        public void onComplete(String arg0, Object arg1) {}
        });
      }
     }
    }
    
    
  • En iOS :
    La función de seguimiento permite rastrear cuándo se activan las notificaciones (aperturas).
    (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)launchOptions
    fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
    {
    if( launchOptions ) { // Retrieve notification parameters here ... // Track application opening Neolane_SDK
    *nl = [Neolane_SDK getInstance]; [nl track:launchOptions:NL_TRACK_CLICK]; } 
    ...  
    completionHandler(UIBackgroundFetchResultNoData);
    }
    
    
    En la versión 7.0, una vez que la función application:didReceiveRemoteNotification:fetchCompletionHandler está implementada, el sistema operativo solo llama a esta función. Por lo tanto, no se llama a la función application:didReceiveRemoteNotification .

Seguimiento de notificaciones silenciosas

iOS permite enviar notificaciones silenciosas, una notificación o datos que se envían directamente a una aplicación móvil sin mostrarlo. Adobe Campaign permite rastrearlas.
Para rastrear una notificación silenciosa, siga el ejemplo a continuación:
// AppDelegate.m
...
...
#import "AppDelegate.h"
#import "Neolane_SDK.h"
...
...
// Callback called when the application is already launched (whether the application is running foreground or background)
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)launchOptions fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
 NSLog(@"IN didReceiveRemoteNotification:fetchCompletionHandler");
 if (launchOptions) NSLog(@"IN launchOptions: %@", [launchOptions description]);
 NSLog(@"Application state: %ld", (long)application.applicationState);

 // Silent Notification (specific case, can use NL_TRACK_RECEIVE as the user doesn't have click/open the notification)
 if ([launchOptions[@"aps"][@"content-available"] intValue] == 1 )
       {
  NSLog(@"Silent Push Notification");
  ...  
  ...
  //Call receive tracking
        Neolane_SDK *nl = [Neolane_SDK getInstance];
  [nl track:launchOptions:NL_TRACK_RECEIVE];

  completionHandler(UIBackgroundFetchResultNoData); //Do not show notification
  return;
 }  
 ...
 ...
        completionHandler(UIBackgroundFetchResultNoData);
}

Delegado RegisterDeviceStatus

Tenga en cuenta que esto es exclusivo de iOS.
En iOS, este protocolo delegado permite obtener el resultado de la llamada a registerDevice y se puede utilizar para saber si se ha producido un error durante el registro.
El prototipo de registerDeviceStatus es:
- (void) registerDeviceStatus: (ACCRegisterDeviceStatus) status:(NSString *) errorReason;

Status permite saber si un registro se ha realizado correctamente o si se ha producido un error.
ErrorReason proporciona más información sobre los errores que se han producido. Para obtener más información sobre los errores disponibles y sus descripciones, consulte la tabla siguiente.
Estado Descripción ErrorReason
ACCRegisterDeviceStatusSuccess Registro con éxito VACÍO
ACCRegisterDeviceStatusFailureMarketingServerHostnameEmpty El nombre de anfitrión del servidor de marketing ACC está vacío o no se ha definido. VACÍO
ACCRegisterDeviceStatusFailureIntegrationKeyEmpty La clave de integración está vacía o no se ha definido. VACÍO
ACCRegisterDeviceStatusFailureConnectionIssue Problema de conexión con ACC Más información (en el idioma actual de OS)
ACCRegisterDeviceStatusFailureUnknownUUID Se desconoce la UUID (clave de integración) proporcionada. VACÍO
ACCRegisterDeviceStatusFailureUnexpectedError Error inesperado devuelto al servidor ACC. El mensaje de error devuelto a ACC.
El protocolo Neolane_SDKDelegate y la definición delegada registerDeviceStatus son las siguientes:
//  Neolane_SDK.h
//  Neolane SDK
..
.. 
// Register Device Status Enum
typedef NS_ENUM(NSUInteger, ACCRegisterDeviceStatus) {
 ACCRegisterDeviceStatusSuccess,                               // Resistration Succeed
 ACCRegisterDeviceStatusFailureMarketingServerHostnameEmpty,   // The ACC marketing server hostname is Empty or not set
 ACCRegisterDeviceStatusFailureIntegrationKeyEmpty,            // The integration key is empty or not set
 ACCRegisterDeviceStatusFailureConnectionIssue,                // Connection issue with ACC, more information in errorReason
 ACCRegisterDeviceStatusFailureUnknownUUID,                    // The provided UUID (integration key) is unknown
 ACCRegisterDeviceStatusFailureUnexpectedError                 // Unexpected error returned by ACC server, more information in errorReason
};
// define the protocol for the registerDeviceStatus delegate
@protocol Neolane_SDKDelegate <NSObject>
@optional
- (void) registerDeviceStatus: (ACCRegisterDeviceStatus) status :(NSString *) errorReason;
@end
@interface Neolane_SDK: NSObject {
} 
...
...
// registerDeviceStatus delegate
@property (nonatomic, weak) id <Neolane_SDKDelegate> delegate;
...
...
@end

Para implementar el delegado registerDeviceStatus , siga estos pasos:
  1. Implemente setDelegate durante la inicialización del SDK.
    // AppDelegate.m
    ...
    ... 
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
    ...
    ...
     // Get the stored settings
    
     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
     NSString *strMktHost = [defaults objectForKey:@"mktHost"];
     NSString *strTckHost = [defaults objectForKey:@"tckHost"];
     NSString *strIntegrationKey = [defaults objectForKey:@"integrationKey"];
     userKey = [defaults objectForKey:@"userKey"];
    
     // Configure Neolane SDK on first launch
     Neolane_SDK *nl = [Neolane_SDK getInstance];
     [nl setMarketingHost:strMktHost];
     [nl setTrackingHost:strTckHost];
     [nl setIntegrationKey:strIntegrationKey];
     [nl setDelegate:self];    // HERE
    ...
    ...
    }
    
    
  2. Añada el protocolo en la @interface de su clase.
    //  AppDelegate.h
    
    #import <UIKit/UIKit.h>
    #import <CoreLocation/CoreLocation.h>
    #import "Neolane_SDK.h"
    
    @class LandingPageViewController;
    
    @interface AppDelegate : UIResponder <UIApplicationDelegate, CLLocationManagerDelegate, Neolane_SDKDelegate> {
        CLLocationManager *locationManager;
        NSString *userKey;
        NSString *mktServerUrl;
        NSString *tckServerUrl;
        NSString *homeURL;
        NSString *strLandingPageUrl;
        NSTimer *timer;
    }
    
    
  3. Implemente el delegado en AppDelegate .
    //  AppDelegate.m
    
    #import "AppDelegate.h"
    #import "Neolane_SDK.h"
    #import "LandingPageViewController.h"
    #import "RootViewController.h"
    ...
    ...
    - (void) registerDeviceStatus: (ACCRegisterDeviceStatus) status :(NSString *) errorReason
    {
        NSLog(@"registerStatus: %lu",status);
    
        if ( errorReason != nil )
            NSLog(@"errorReason: %@",errorReason);
    
        if( status == ACCRegisterDeviceStatusSuccess )
        {
            // Registration successful
            ...
            ...
        }
        else { // An error occurred
            NSString *message;
            switch ( status ){
                case ACCRegisterDeviceStatusFailureUnknownUUID:
                    message = @"Unkown IntegrationKey (UUID)";
                    break;
                case ACCRegisterDeviceStatusFailureMarketingServerHostnameEmpty:
                    message = @"Marketing URL not set or Empty";
                    break;
                case ACCRegisterDeviceStatusFailureIntegrationKeyEmpty:
                    message = @"Integration Key not set or empty";
                    break;
                case ACCRegisterDeviceStatusFailureConnectionIssue:
                    message = [NSString stringWithFormat:@"%@ %@",@"Connection issue:",errorReason];
                    break;
                case ACCRegisterDeviceStatusFailureUnexpectedError:
                default:
                    message = [NSString stringWithFormat:@"%@ %@",@"Unexpected Error",errorReason];
                    break;
            }
     ...
     ...
        }
    }
    @end
    
    

Variables

Las variables permiten definir el comportamiento de la aplicación móvil después de recibir una notificación. Estas se deben definir en el código de la aplicación móvil y en la consola de Adobe Campaign, en la pestaña Variables del servicio dedicado de la aplicación móvil (consulte Configuración de una aplicación móvil en Adobe Campaign ). A continuación, se muestra un ejemplo de código que permite a una aplicación móvil recopilar variables añadidas en una notificación. En este ejemplo, se utiliza la variable “VAR”.
  • En Android :
    public void onReceive(Context context, Intent intent) {
         ...
        String event = intent.getStringExtra("VAR");
         ...
    }
    
    
  • En iOS :
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        ....
        if( launchOptions )
        {
            // When application is not already launched, the notification data if any are stored in the key 'UIApplicationLaunchOptionsRemoteNotificationKey'
            NSDictionary *localLaunchOptions = [launchOptions objectForKey:@"UIApplicationLaunchOptionsRemoteNotificationKey"];
            if( localLaunchOptions )
            {
             ...
             [localLaunchOptions objectForKey:@"VAR"];
            ...
            }
       }
    }
    
    // Callback called when the application is already launched (whether the application is running foreground or background)
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)launchOptions
    {
        if( launchOptions )
        {
         ...
            [launchOptions objectForKey:@"VAR"];
        }
    }
    
    
Adobe recomienda elegir nombres de variables cortos debido a que el tamaño de notificación está limitado a 4 kB para iOS y Android.

Extensión de servicio de notificaciones

Para iOS
Los medios deben descargarse en el nivel de extensión del servicio de notificación.
#import "NotificationService.h"

@interface NotificationService ()

@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;

@end

@implementation NotificationService

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    NSDictionary *userInfo = nil;
    NSString *url = nil;

    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];

    userInfo = request.content.userInfo;
    if ( userInfo != nil )
    {
        url = userInfo[@"mediaUrl"];  // Get the url of the media to download (Adobe Campaign additional variable)
    }
    ...
    // Perform the download to local storage

Extensión de contenido de notificación

Para iOS
A este nivel, es necesario:
  • Asocie la extensión de contenido a la categoría enviada por Adobe Campaign:
    Si desea que la aplicación móvil muestre una imagen, puede establecer el valor de la categoría en “imagen” en Adobe Campaign y crear en la aplicación móvil una extensión de notificación con el parámetro UNNotificationExtensionCategory establecido en “imagen”. Cuando se recibe la notificación push en el dispositivo, se llama a la extensión según el valor de categoría definido.
  • Definición del diseño de la notificación
    Se debe definir el diseño con elementos gráficos relevantes. Para una imagen, el elemento gráfico se denomina UIImageView .
  • Visualización de sus medios
    Se debe añadir código para enviar los datos de medios al widget. A continuación, se muestra un ejemplo de código para una imagen:
    #import "NotificationViewController.h"
    #import <UserNotifications/UserNotifications.h>
    #import <UserNotificationsUI/UserNotificationsUI.h>
    
    @interface NotificationViewController () <UNNotificationContentExtension>
    
    @property (strong, nonatomic) IBOutlet UIImageView *imageView;
    @property (strong, nonatomic) IBOutlet UILabel *notifContent;
    @property (strong, nonatomic) IBOutlet UILabel *label;
    
    @end
    
    @implementation NotificationViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any required interface initialization here.
    }
    
    - (void)didReceiveNotification:(UNNotification *)notification {
        self.label.text = notification.request.content.title;
        self.notifContent.text = notification.request.content.body;
        UNNotificationAttachment *attachment = [notification.request.content.attachments objectAtIndex:0];
        if ([attachment.URL startAccessingSecurityScopedResource])
        {
          NSData * imageData = [[NSData alloc] initWithContentsOfURL:attachment.URL];
          self.imageView.image =[UIImage imageWithData: imageData];
          [attachment.URL stopAccessingSecurityScopedResource];
        }
    }
    @end