Integración del SDK de Campaign con la aplicación integrating-campaign-sdk-into-the-mobile-application

CAUTION
Adobe recomienda encarecidamente utilizar el SDK móvil de Adobe Experience Platform configurando la extensión de Adobe Campaign en la interfaz de usuario de recopilación de datos. El SDK móvil de Adobe Experience Platform impulsa las soluciones y los servicios Experience Cloud de Adobe en sus aplicaciones móviles. La configuración de los SDK se administra mediante la interfaz de usuario de recopilación de datos para lograr una configuración flexible e integraciones ampliables basadas en reglas. Obtenga más información en la documentación de Adobe Developer.

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.

Para obtener más información sobre las diferentes versiones de iOS y Android compatibles, consulte la matriz de compatibilidad.

A continuación se muestran los pasos de integración para el SDK de Campaign.

Carga del 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:

    code language-none
    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 el ID único de un teléfono móvil:

    code language-none
    <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.

    note note
    NOTE
    Para la versión 1.0.25 del SDK, las cuatro arquitecturas están disponibles en el archivo Neolane_SDK.h .
Declaración de las 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.

    note note
    NOTE
    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:

    code language-none
    Neolane.getInstance().setIntegrationKey("your Adobe mobile app integration key");
    Neolane.getInstance().setMarketingHost("https://yourMarketingHost:yourMarketingPort/");
    Neolane.getInstance().setTrackingHost("https://yourTrackingHost:yourTrackingPort/");
    
  • En iOS:

    code language-none
    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:

    code language-none
    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.

    code language-none
    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:

    code language-none
    // 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.

    code language-none
    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);
      }
    }
    
    code language-none
    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
      SharedPreferences settings = context.getSharedPreferences(NeoTripActivity.APPLICATION_PREF_NAME, Context.MODE_PRIVATE);
      Neolane.getInstance().setIntegrationKey(settings.getString(NeoTripActivity.APPUUID_NAME, NeoTripActivity.DFT_APPUUID));
      Neolane.getInstance().setMarketingHost(settings.getString(NeoTripActivity.SOAPRT_NAME, NeoTripActivity.DFT_SOAPRT));
      Neolane.getInstance().setTrackingHost(settings.getString(NeoTripActivity.TRACKRT_NAME, NeoTripActivity.DFT_TRACKRT));
    
      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.

    code language-none
    public class NotificationActivity extends Activity {
    public void onCreate(Bundle savedBundle) {
      [...]
      Bundle extra = getIntent().getExtras();
      if (extra != null) {
        // reinit the acc sdk
        SharedPreferences settings = getSharedPreferences(NeoTripActivity.APPLICATION_PREF_NAME, Context.MODE_PRIVATE);
        Neolane.getInstance().setIntegrationKey(settings.getString(NeoTripActivity.APPUUID_NAME, NeoTripActivity.DFT_APPUUID));
        Neolane.getInstance().setMarketingHost(settings.getString(NeoTripActivity.SOAPRT_NAME, NeoTripActivity.DFT_SOAPRT));
        Neolane.getInstance().setTrackingHost(settings.getString(NeoTripActivity.TRACKRT_NAME, NeoTripActivity.DFT_TRACKRT));
    
        // 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) {
          try {
            Neolane.getInstance().notifyOpening(Integer.valueOf(messageId), Integer.valueOf(deliveryId));
          } catch (NeolaneException e) {
            // ...
          } catch (IOException e) {
            // ...
          }
        }
      }
     }
    }
    
  • En iOS:

    La función de seguimiento permite rastrear cuándo se activan las notificaciones (aperturas).

    code language-none
    (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);
    }
    
    note note
    NOTE
    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 las 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:

code language-none
// 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
note note
NOTE
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:

code language-none
- (void) registerDeviceStatus: (ACCRegisterDeviceStatus) status:(NSString *) errorReason;

El estado 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.

table 0-row-3 1-row-3 2-row-3 3-row-3 4-row-3 5-row-3 6-row-3
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:

code language-none
//  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.

    code language-none
    // 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.

    code language-none
    //  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.

    code language-none
    //  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 variables 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 de la aplicación móvil dedicada (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:

    code language-none
    public void onReceive(Context context, Intent intent) {
         ...
        String event = intent.getStringExtra("VAR");
         ...
    }
    
  • En iOS:

    code language-none
    - (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"];
        }
    }
    
note caution
CAUTION
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.

code language-none
#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:

    code language-none
    #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
    
recommendation-more-help
601d79c3-e613-4db3-889a-ae959cd9e3e1