Campaign SDK とアプリの統合 integrating-campaign-sdk-into-the-mobile-application
Campaign SDK(旧 Neolane SDK)を入手するには、アドビカスタマーケアにお問い合わせください。
サポートされている様々な Android および iOS バージョンについて詳しくは、互換性マトリックスを参照してください。
Campaign SDK の統合手順を以下に示します。
-
Android の場合:neolane_sdk-release.aar ファイルがプロジェクトにリンクされている必要があります。
以下の権限により、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/");
以下の権限を持っている場合は、モバイルの一意の ID を復元できます。
code language-none <uses-permission android:name="android.permission.READ_PHONE_STATE" />
SDK バージョン 1.0.24 以降、この権限は Android 6.0 よりも古いバージョンでのみ使用されます。
SDK バージョン 1.0.26 以降では、この権限は使用されません。
-
iOS の場合:libNeolaneSDK.a ファイルと Neolane_SDK.h ファイルがプロジェクトにリンクされている必要があります。SDK バージョン 1.0.24 以降は、ENABLE_BITCODE オプションが有効になります。
note note NOTE バージョン 1.0.25 の SDK の場合は、Neolane_SDK.h ファイルに 4 つのアーキテクチャがあります。
Campaign SDK をモバイルアプリケーションに統合するには、担当の管理者がデベロッパーに次の情報を提供する必要があります。
-
統合キー:Adobe Campaign プラットフォームでモバイルアプリケーションを特定できるようにします。
note note NOTE この統合キーは、Adobe Campaign コンソールのモバイルアプリケーション専用サービスの「情報」タブに入力されます。詳しくは、Adobe Campaign でモバイルアプリケーションを設定するを参照してください。 -
トラッキング URL:Adobe Campaign トラッキングサーバーのアドレスと一致します。
-
マーケティング URL:購読のコレクションを有効にします。
-
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/");
-
iOS:
code language-none 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:
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){ //... } }
FCM(Firebase Cloud Messaging)を使用する場合は、onTokenRefresh 関数を呼び出して Adobe Campaign にユーザーのモバイルデバイストークンの変更を通知するときに、registerDevice 関数を使用することをお勧めします。
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) { ... } }); ... ... } }
-
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]; }
-
Android:
トラッキング関数を使用すると、通知の有効化(オープン)および通知の表示(スクリーンショット)を追跡できます。
(SDK の notifyReceive 関数を呼び出して)通知表示をトラッキングするには、次の実装に従います。FCM(Firebase Cloud Messaging)を使用する場合は、Android システムによって onMessageReceived 関数が呼び出されるときに notifyReceive 関数を使用することをお勧めします。
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); } }
次に、通知の開封をトラッキングする実装例を示します(SDK の notifyOpening 関数を呼び出して実行します)。NotificationActivity クラスには、前の例で notifIntent オブジェクトを作成する際に使用したクラスが該当します。
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) { // ... } } } } }
-
iOS:
トラッキング関数を使用すると、通知の有効化(オープン)を追跡できます。
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 バージョン 7.0 以降は、 application:didReceiveRemoteNotification:fetchCompletionHandler
関数を実装すると、オペレーティングシステムはこの関数のみを呼び出します。したがって、application:didReceiveRemoteNotification
関数は呼び出されません。
iOS では、無音の通知(表示されることなくモバイルアプリケーションに直接送信される通知またはデータ)を送信できます。Adobe Campaign では、このような通知をトラッキングすることができます。
無音の通知をトラッキングするには、以下の例に従います。
code language-none |
---|
|
note note |
---|
NOTE |
これは iOS 専用です。 |
iOS では、このデリゲートプロトコルを使用すると、registerDevice 呼び出しの結果を取得でき、登録時にエラーが発生したかどうかを把握できます。
registerDeviceStatus のプロトタイプは次のとおりです。
code language-none |
---|
|
status を使用すると、登録が成功したかどうかやエラーが発生したかどうかを把握できます。
ErrorReason:発生したエラーに関する詳細情報を提供します。使用可能なエラーとその説明について詳しくは、以下の表を参照してください。
table 0-row-3 1-row-3 2-row-3 3-row-3 4-row-3 5-row-3 6-row-3 | ||
---|---|---|
ステータス | 説明 | ErrorReason |
ACCRegisterDeviceStatusSuccess | 登録が成功しました | 空 |
ACCRegisterDeviceStatusFailureMarketingServerHostnameEmpty | ACC マーケティングサーバーのホスト名が空であるか、設定されていません。 | 空 |
ACCRegisterDeviceStatusFailureIntegrationKeyEmpty | 統合キーが空であるか、設定されていません。 | 空 |
ACCRegisterDeviceStatusFailureConnectionIssue | ACC との接続の問題 | (OS の現在の言語での)詳細情報 |
ACCRegisterDeviceStatusFailureUnknownUUID | 指定された UUID(統合キー)が不明です。 | 空 |
ACCRegisterDeviceStatusFailureUnexpectedError | 予期しないエラーが ACC サーバーに返されました。 | エラーメッセージが ACC に返されました。 |
Neolane_SDKDelegate プロトコルと registerDeviceStatus デリゲートの定義は次のとおりです。
code language-none |
---|
|
RegisterDeviceStatus デリゲートを実装するには、以下の手順を実行します。
-
SDK の初期化中に setDelegate を実装します。
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 ... ... }
-
クラスの @interface にプロトコルを追加します。
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; }
-
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
変数を使用すれば、通知を受信した後のモバイルアプリケーションの動作を定義できます。これらの変数は、モバイルアプリケーションのコードと、Adobe Campaign コンソールのモバイルアプリケーション専用の「変数」タブで定義する必要があります(Adobe Campaign でモバイルアプリケーションを設定するを参照)。次に、モバイルアプリケーションが通知で追加された変数を収集できるようにするコードの例を示します。この例では、「VAR」変数を使用しています。
-
Android:
code language-none public void onReceive(Context context, Intent intent) { ... String event = intent.getStringExtra("VAR"); ... }
-
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 |
iOS と Android では通知のサイズが 4 KB に制限されているので、短い変数名を選択することをお勧めします。 |
iOS の場合
メディアは通知サービス拡張レベルでダウンロードする必要があります。
code language-none |
---|
|
iOS の場合
このレベルでは次の作業が必要です。
-
Adobe Campaign が送信したカテゴリにコンテンツ拡張を関連付けます。
モバイルアプリケーションで画像を表示できるようにするには、Adobe Campaign とモバイルアプリケーションでカテゴリの値を「画像」に設定し、通知拡張を作成して UNNotificationExtensionCategory パラメーターを「画像」に設定します。デバイスがプッシュ通知を受信した場合、定義されたカテゴリの値に従って拡張機能が呼び出されます。
-
通知レイアウトの定義
関連するウィジェットでレイアウトを定義する必要があります。画像の場合、ウィジェットの名前は UIImageView です。
-
メディアの表示
メディアデータをウィジェットに送るためのコードを追加する必要があります。画像用のコードの例を次に示します。
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