将Campaign SDK与您的应用程序集成

适用于iOS和Android的Campaign SDK是移动设备应用程序渠道模块的组件之一。

注意

要获取Campaign SDK(以前称为Neolane SDK),请联系 Adobe客户关怀

SDK的目标是促进将移动应用程序集成到Adobe Campaign平台。

要了解有关支持的不同Android和iOS版本的更多信息,请参阅 兼容性矩阵.

注意

您还可以通过在Launch中配置Adobe Experience Platform扩展来使用Adobe Campaign Mobile SDK。 在Adobe Experience Platform文档中了解详情

了解如何配置和安装Adobe Experience Platform Mobile SDK 在此视频中

加载Campaign SDK

  • 在Android中:the neolane_sdk-release.aar 文件必须链接到项目。

    以下权限授予对Adobe Campaign服务器的访问权限:

    Neolane.getInstance().setIntegrationKey("your Adobe mobile app integration key");
    Neolane.getInstance().setMarketingHost("https://yourMarketingHost:yourMarketingPort/");
    Neolane.getInstance().setTrackingHost("https://yourTrackingHost:yourTrackingPort/");
    

    以下权限允许您恢复电话的唯一ID:

    <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
    

    从SDK版本1.0.24开始,此权限仅用于Android 6.0以前的版本。

    从SDK版本1.0.26开始,将不再使用此权限。

  • 在iOS:the libNeolaneSDK.aNeolane_SDK.h 文件必须链接到项目。 从SDK版本1.0.24开始, ENABLE_BITCODE 激活。

    注意

    对于SDK版本1.0.25,在 Neolane_SDK.h 文件。

声明集成设置

要将Campaign SDK集成到移动应用程序中,功能管理员必须向开发人员提供以下信息:

  • 集成密钥:以启用Adobe Campaign平台来识别移动应用程序。

    注意

    此集成密钥是在Adobe Campaign控制台(位于 Information 专用于移动应用程序的服务选项卡。 请参阅 在Adobe Campaign中配置移动应用程序.

  • 跟踪URL:与Adobe Campaign跟踪服务器的地址匹配。

  • 营销URL:以启用订阅的收集。

  • 在Android中:

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

    Neolane_SDK *nl = [Neolane_SDK getInstance];
    [nl setMarketingHost:strMktHost];
    [nl setTrackingHost:strTckHost];
    [nl setIntegrationKey:strIntegrationKey];
    

注册功能

注册功能允许您:

  • 将通知ID或推送ID(iOS的deviceToken和Android的registrationID)发送到Adobe Campaign。

  • 恢复协调密钥或userKey(例如,电子邮件或帐号)

  • 在Android中:

    void registerInNeolane(String registrationId, String userKey, Context context)
    {
     try{
      Neolane.getInstance().registerDevice(registrationToken, userKey, null, context);
     } catch (NeolaneException e){
      //...
     } catch (IOException e){
      //...
     }
    }
    

    如果您使用FCM(Firebase Cloud Messaging),我们建议您使用 registerDevice 函数 onTokenRefresh 函数,以通知Adobe Campaign用户移动设备令牌发生更改。

    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) { ... }
        });
        ...
        ...
      }
    }
    
  • 在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];
    }
    

跟踪函数

  • 在Android中:

    跟踪函数允许您跟踪通知激活(打开)和通知显示(屏幕截图)。

    跟踪通知显示(通过调用 notifyReceive 函数),请按照以下实施操作。 请注意,如果您使用FCM(Firebase Cloud Messaging),我们建议您使用 notifyReceive 函数 onMessageReceived 函数由Android系统调用。

    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
      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);
        }
    }
    

    以下是用于跟踪打开的通知(通过调用 notifyOpening 函数)。 的 NotificationActivity 类对应于用于创建 notifIntent 对象。

    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) {
            // ...
          }
        }
      }
     }
    }
    
  • 在iOS:

    利用跟踪函数,可在激活(打开)通知时进行跟踪。

    (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);
    }
    
    注意

    从版本7.0开始, 应用程序:didReceiveRemoteNotification:fetchCompletionHandler 函数,操作系统仅调用此函数。 的 application:didReceiveRemoteNotification 因此,不会调用函数。

无提示通知跟踪

iOS允许您发送静默通知、通知或数据,这些通知或数据将直接发送到移动应用程序,而不显示。 Adobe Campaign允许您跟踪它们。

要跟踪无提示通知,请按照以下示例操作:

// 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);
}

RegisterDeviceStatus委托

注意

请注意,这是iOS专有的。

在iOS中,委托协议允许您获取 registerDevice 调用和,可用于知道注册期间是否发生错误。

registerDeviceStatus 原型为:

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

状态 用于了解注册是否成功或是否发生错误。

错误原因 为您提供有关所发生错误的更多信息。 有关可用错误及其说明的更多信息,请参阅下表。

状态
说明
错误原因
ACCRegisterDeviceStatusSuccess
注册成功
EMPTY
ACCRegisterDeviceStatusFailureMarketingServerHostnameEmpty
ACC营销服务器主机名为空或未设置。
EMPTY
ACCRegisterDeviceStatusFailureIntegrationKeyEmpty
集成键值为空或未设置。
EMPTY
ACCRegisterDeviceStatusFailureConnectionIssue
与ACC的连接问题
更多信息(使用操作系统当前语言)
ACCRegisterDeviceStatusFailureUnknownUUID
提供的UUID(集成密钥)未知。
EMPTY
ACCRegisterDeviceStatusFailureExpectedError
向ACC服务器返回意外错误。
返回到ACC的错误消息。

Neolane_SDKelegate 协议和 registerDeviceStatus 委托定义如下所示:

//  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

实施 registerDeviceStatus 委派,请执行以下步骤:

  1. 实施 setDelegate 在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. @interface 你班的。

    //  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. 在中实施委托 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
    

变量

利用变量,可在收到通知后定义移动应用程序行为。 这些变量必须在移动设备应用程序代码和Adobe Campaign控制台(位于 Variables 选项卡(请参阅 在Adobe Campaign中配置移动应用程序)。 以下代码示例允许移动设备应用程序收集通知中任何添加的变量。 在我们的示例中,我们使用“VAR”变量。

  • 在Android中:

    public void onReceive(Context context, Intent intent) {
         ...
        String event = intent.getStringExtra("VAR");
         ...
    }
    
  • 在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建议选择短变量名称,因为对于iOS和Android,通知大小限制为4kB。

通知服务扩展

对于iOS

必须在通知服务扩展级别下载媒体。

#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

通知内容扩展

对于iOS

在此级别,您需要:

  • 将内容扩展关联到由Adobe Campaign发送的类别:

    如果您希望移动应用程序显示图像,则可以在Adobe Campaign中将类别值设置为“image”,并在移动应用程序中,使用 UNNotificationExtensionCategory 参数设置为“image”。 在设备上收到推送通知时,将根据定义的类别值调用扩展。

  • 定义通知布局

    您需要使用相关小组件定义布局。 对于图像,小组件名为 UIImageView.

  • 显示媒体

    您需要添加代码以将媒体数据馈送到小组件。 以下是图像的代码示例:

    #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
    

在此页面上