React Native
本文提供如何安裝和設定Marketo的原生SDK,以將您的行動應用程式與我們的平台整合的相關資訊。
先決條件
在Marketo Admin中新增應用程式 (取得您的應用程式秘密金鑰和Munchkin ID)。
SDK整合
Android SDK整合
使用Gradle進行安裝
使用最新版本新增Marketo SDK相依性:在應用程式層級build.gradle
檔案的相依性區段下方,新增(包括適當版本的Marketo SDK)
implementation 'com.marketo:MarketoSDK:0.x.x'
新增mavencentral存放庫
maven中央存放庫提供Marketo SDK。 若要同步處理這些檔案,請新增mavencentral
存放庫至根build.gradle
build script {
repositories {
google()
mavencentral()
}
}
然後,將您的專案與Gradle檔案同步。
iOS SDK整合
在您為React Native專案建立Bridge之前,請務必在Xcode專案中設定我們的SDK。
SDK整合 — 使用CocoaPods
在應用程式中使用我們的iOS SDK相當容易。 執行以下步驟,透過CocoaPods在應用程式的Xcode專案中進行設定,將我們的平台與應用程式整合。
下載CocoaPods — 以Ruby gem形式發佈,它是Objective-C和Swift的相依性管理員,可簡化程式碼中使用協力廠商程式庫(例如iOS SDK)的程式。
若要下載並安裝,請在Mac上啟動命令列終端機,並在其上執行下列命令:
- 安裝CocoaPods。
$ sudo gem install cocoapods
- 開啟您的Podfile。 (在ReactNative專案的iOS資料夾內)
$ open -a Xcode Podfile
- 將下列行新增至您的Podfile。
$ pod 'Marketo-iOS-SDK'
-
儲存並關閉您的Podfile。
-
下載並安裝Marketo iOS SDK。
$ pod install
- 在Xcode中開啟工作區。
$ open App.xcworkspace
原生模組安裝指示
有時React Native應用程式需要存取JavaScript中預設不可用的原生平台API,例如存取Apple或Google Pay的原生API。 您可能想要重複使用一些現有的Objective-C、Swift、Java或C++程式庫,而不需要在JavaScript中重新實作,或針對影像處理等作業編寫一些高效能的多執行緒程式碼。
NativeModule系統向JavaScript (JS)公開Java/Objective-C/C++ (原生)類別的執行個體,做為JS物件,因此可讓您從JS內執行任意原生程式碼。 雖然我們不預期此功能會成為一般開發流程的一部分,但必須具備此功能。 如果React Native未匯出JS應用程式所需的原生API,您應該能夠自行匯出!
React Native Bridge可用來在JSX和原生應用程式層之間通訊。 在此情況下,主機應用程式將能撰寫可叫用Marketo SDK方法的JSX程式碼。
Android
此檔案包含可以使用您提供的引數在內部呼叫Marketo SDK方法的包裝函式方法。
public class RNMarketoModule extends ReactContextBaseJavaModule {
final Marketo marketoSdk;
RNMarketoModule(ReactApplicationContext context) {
super(context);
marketoSdk = Marketo.getInstance(context);
}
@NonNull
@Override
public String getName() {
return "RNMarketoModule";
}
@ReactMethod
public void associateLead(ReadableMap leadData) {
MarketoLead mLead = new MarketoLead();
try {
mLead.setCity(leadData.getString(MarketoLead.KEY_CITY));
mLead.setFirstName(leadData.getString(MarketoLead.KEY_FIRST_NAME));
mLead.setLastName(leadData.getString(MarketoLead.KEY_LAST_NAME));
mLead.setAddress(leadData.getString(MarketoLead.KEY_ADDRESS));
mLead.setEmail(leadData.getString(MarketoLead.KEY_EMAIL));
mLead.setBirthDay(leadData.getString(MarketoLead.KEY_BIRTHDAY));
mLead.setCountry(leadData.getString(MarketoLead.KEY_COUNTRY));
mLead.setFacebookId(leadData.getString(MarketoLead.KEY_FACEBOOK));
mLead.setGender(leadData.getString(MarketoLead.KEY_GENDER));
mLead.setState(leadData.getString(MarketoLead.KEY_STATE));
mLead.setPostalCode(leadData.getString(MarketoLead.KEY_POSTAL_CODE));
mLead.setTwitterId(leadData.getString(MarketoLead.KEY_TWITTER));
marketoSdk.associateLead(mLead);
}
catch (MktoException e){
}
}
@ReactMethod
public void setSecureSignature(ReadableMap readableMap) {
MarketoConfig.SecureMode secureMode = new MarketoConfig.SecureMode();
secureMode.setAccessKey(readableMap.getString("accessKey"));
secureMode.setEmail(readableMap.getString("email"));
secureMode.setSignature(readableMap.getString("signature"));
secureMode.setTimestamp(readableMap.getInt("timeStamp"));
marketoSdk.setSecureSignature(secureMode);
}
@ReactMethod
public void initializeSDK(String frameworkType, String munchkinId, String appSecreteKey){
marketoSdk.initializeSDK(munchkinId,appSecreteKey,frameworkType);
}
@ReactMethod
public void initializeMarketoPush(String projectId){
marketoSdk.initializeMarketoPush( projectId);
}
@ReactMethod
public void initializeMarketoPush(String projectId, String channelName){
marketoSdk.initializeMarketoPush( projectId, channelName);
}
@ReactMethod
public void uninitializeMarketoPush(){
marketoSdk.uninitializeMarketoPush();
}
@ReactMethod
public void reportAction(String action){
Marketo.reportAction(action, null);
}
@ReactMethod
public void reportAction(String action, ReadableMap readableMap){
MarketoActionMetaData marketoActionMetaData = new MarketoActionMetaData();
marketoActionMetaData.setActionDetails(readableMap.getString("setMetric"));
marketoActionMetaData.setActionMetric(readableMap.getString("setLength"));
marketoActionMetaData.setActionLength(readableMap.getString("actionDetails"));
marketoActionMetaData.setActionType(readableMap.getString("actionType"));
Marketo.reportAction(action, marketoActionMetaData);
}
}
登入封裝
告知react-native Marketo套件。
public class MarketoPluginPackage implements ReactPackage {
@NonNull
@Override
public List createNativeModules(@NonNull ReactApplicationContext reactContext) {
List modules = new ArrayList<>();
modules.add(new RNMarketoModule(reactContext));
return modules;
}
@NonNull
@Override
public List createViewManagers(@NonNull ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
若要完成套件註冊,請將MarketoPluginPackage新增至Application Class中的React套件清單:
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost =
new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List packages = new PackageList(this).getPackages();
packages.add(new MarketoPluginPackage()); //Add the Marketo Package here.
// Packages that cannot be autolinked yet can be added manually here, for example:
return packages;
}
}
iOS
在下列指南中,您將建立原生模組 RNMarketoModule,此模組可讓您從JavaScript存取Marketo的API。
若要開始使用,請在Xcode的React Native應用程式中開啟iOS專案。 您可以在React Native應用程式中找到您的iOS專案。 建議您使用Xcode來撰寫原生程式碼。 Xcode是專為iOS開發所建置,使用它可以協助您快速解決小錯誤,例如程式碼語法。
建立主要自訂原生模組標頭和實施檔案。 建立名為MktoBridge.h
的新檔案,並新增下列內容:
//
// MktoBridge.h
//
// Created by Marketo, An Adobe company.
//
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
NS_ASSUME_NONNULL_BEGIN
@interface MktoBridge : NSObject
@end
NS_ASSUME_NONNULL_END
在相同資料夾中建立對應的實作檔案MktoBridge.m
,並包含下列內容:
//
// MktoBridge.h
// Created by Marketo, An Adobe company.
//
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
NS_ASSUME_NONNULL_BEGIN
@interface MktoBridge : NSObject <RCTBridgeModule>
@end
NS_ASSUME_NONNULL_END
//
// MktoBridge.m
// Created by Marketo, An Adobe company.
//
#import "MktoBridge.h"
#import <MarketoFramework/Marketo.h>
#import <React/RCTBridge.h>
#import "ConstantStringsHeader.h"
@implementation MktoBridge
RCT_EXPORT_MODULE(RNMarketoModule);
+(BOOL)requiresMainQueueSetup{
return NO;
}
RCT_EXPORT_METHOD(initializeSDK:(NSString *) munchkinId SecretKey: (NSString *) secretKey andFrameworkType: (NSString *) frameworkType){
[[Marketo sharedInstance] initializeWithMunchkinID:munchkinId appSecret:secretKey mobileFrameworkType:frameworkType launchOptions:nil];
}
RCT_EXPORT_METHOD(reportAction:(NSString *)actionName withMetaData:(NSDictionary *)metaData){
MarketoActionMetaData *meta = [[MarketoActionMetaData alloc] init];
[meta setType:[metaData objectForKey:KEY_ACTION_TYPE]];
[meta setDetails:[metaData objectForKey:KEY_ACTION_DETAILS]];
[meta setLength:[metaData valueForKey:KEY_ACTION_LENGTH]];
[meta setMetric:[metaData valueForKey:KEY_ACTION_METRIC]];
[[Marketo sharedInstance] reportAction:actionName withMetaData:meta];
}
RCT_EXPORT_METHOD(associateLead:(NSDictionary *)leadDetails){
MarketoLead *lead = [[MarketoLead alloc] init];
if ([leadDetails objectForKey:KEY_EMAIL] != nil) {
[lead setEmail:[leadDetails objectForKey:KEY_EMAIL]];
}
if ([leadDetails objectForKey:KEY_FIRST_NAME] != nil) {
[lead setFirstName:[leadDetails objectForKey:KEY_FIRST_NAME]];
}
if ([leadDetails objectForKey:KEY_LAST_NAME] != nil) {
[lead setLastName:[leadDetails objectForKey:KEY_LAST_NAME]];
}
if ([leadDetails objectForKey:KEY_CITY] != nil) {
[lead setCity:[leadDetails objectForKey:KEY_CITY]];
}
[[Marketo sharedInstance] associateLead:lead];
}
RCT_EXPORT_METHOD(uninitializeMarketoPush){
[[Marketo sharedInstance] unregisterPushDeviceToken];
}
RCT_EXPORT_METHOD(reportAll){
[[Marketo sharedInstance] reportAll];
}
RCT_EXPORT_METHOD(setSecureSignature:(NSDictionary *)secureSignature){
MKTSecuritySignature *secSignature = [[MKTSecuritySignature alloc]
initWithAccessKey:[secureSignature objectForKey:KEY_ACCESSKEY]
signature:[secureSignature objectForKey:KEY_SIGNATURE]
timestamp: [secureSignature objectForKey:KEY_EMAIL]
email:[secureSignature objectForKey:KEY_EMAIL]];
[[Marketo sharedInstance] setSecureSignature:secSignature];
}
RCT_EXPORT_METHOD(requestPermission:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound + UNAuthorizationOptionBadge)
completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (error) {
reject(@"PERMISSION_ERROR", @"Permission request failed", error);
} else {
resolve(@(granted));
}
}];
}
RCT_EXPORT_METHOD(registerForRemoteNotifications) {
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] registerForRemoteNotifications];
});
}
@end
初始化Marketo SDK
在應用程式中尋找您想要將呼叫新增至原生模組的createCalendarEvent()方法的位置。 以下是您可以在應用程式中新增的元件NewModuleButton範例。 您可以在NewModuleButton的onPress()函式內叫用原生模組。
import React from 'react';
import { NativeModules, Button } from 'react-native';
const NewModuleButton = () => {
const onPress = () => {
console.log('We will invoke the native module here!');
};
return (
);
};
export default NewModuleButton;
此JavaScript檔案會將原生模組載入JavaScript層。
import React from 'react';
import {Node} from 'react';
import { NativeModules } from 'react-native';
const { RNMarketoModule } = NativeModules;
正確放置上述檔案後,我們就可以匯入任何js類別中的js模組,並直接呼叫其方法。 例如:
請注意,我們必須傳遞「reactNative」作為React原生應用程式的框架型別。
// Initialize marketo SDK with Munchkin & Seretkey you have from step 1.
RNMarketoModule.initializeSDK("MunchkinID","SecreteKEY","FrameworkType")
//You can create a Marketo Lead by calling the associateLead function.
RNMarketoModule.associateLead({ email: "", firstName: "", lastName:"", city:""})
//You can report any user performed action by calling the reportaction function.
RNMarketoModule.reportAction("Bought Shirt", {actionType:"Shopping", actionDetails: "Red Shirt", setLength : 20, setMetric : 30 })
//You can set Secure Signature by calling this method.
RNMarketoModule.setSecureSignature({accessKey: "Key102", email: "testleadrk@001.com", signature : "asdfghjkloiuytds", timeStamp: "12345678987654"})
//This function will Enable user notifications (Only Android)
RNMarketoModule.initializeMarketoPush("350312872033", "MKTO")
//The token can also be unregistered on logout.
RNMarketoModule.uninitializeMarketoPush()
設定推播通知
使用專案ID和頻道名稱初始化推播
RNMarketoModule.initializeMarketoPush("ProjectId", "Channel_name")
將下列服務新增至AndroidManifest.xml
<service android:exported="true" android:name=".MyFirebaseMessagingService" android:stopWithTask="true">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter/>
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter/>
</activity/>
建立名稱為FirebaseMessagingService.java
的類別並新增下列程式碼
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import com.marketo.Marketo;
public class MyFirebaseMessagingService extends FirebaseMessagingService {
@Override
public void onNewToken(String token) {
super.onNewToken(token);
Marketo marketoSdk = Marketo.getInstance(this.getApplicationContext());
marketoSdk.setPushNotificationToken(token);
}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Marketo marketoSdk = Marketo.getInstance(this.getApplicationContext());
marketoSdk.showPushNotification(remoteMessage);
}
}
必須在您的Xcode專案中啟用許可權,才能將推播通知傳送至使用者的裝置。
若要傳送推播通知,新增推播通知。
設定iOS推播通知,
建立PushNotifications.tsx檔案並新增下列專案:
import { NativeModules } from 'react-native';
const { RNMarketoModule } = NativeModules;
const requestPermission = (): Promise<boolean> => {
return RNMarketoModule.requestPermission()
.then((granted: boolean) => {
console.log('Permission granted:', granted);
return granted;
})
.catch((error: any) => {
console.error('Permission error:', error);
throw error;
});
};
const registerForRemoteNotifications = (): void => {
RNMarketoModule.registerForRemoteNotifications();
};
export { requestPermission, registerForRemoteNotifications };
新增App.tsx
以允許推播通知
import React, { useEffect } from 'react';
useEffect(() => {
requestPermission().then(granted => {
if (granted) {
registerForRemoteNotifications();
}
});
}, []);
使用APNS委派方法更新AppDelegate.mm
:
#import "AppDelegate.h"
#import "MktoBridge.h"
#import <MarketoFramework/Marketo.h>
#import <React/RCTBundleURLProvider.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.moduleName = @"MyNewApp";
// You can add your custom initial props in the dictionary below.
// They will be passed down to the ViewController used by React Native.
self.initialProps = @{};
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
return [self bundleURL];
}
-(void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void(^)(void))completionHandler {
[[Marketo sharedInstance] userNotificationCenter:center
didReceiveNotificationResponse:response
withCompletionHandler:completionHandler];
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
// Register the push token with Marketo
[[Marketo sharedInstance] registerPushDeviceToken:deviceToken];
}
- (void)applicationWillTerminate:(UIApplication *)application {
[[Marketo sharedInstance] unregisterPushDeviceToken];
}
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
NSLog(@"Failed to register for remote notification - %@", [error userInfo]);
}
- (NSURL *)bundleURL
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}
@end
新增測試裝置
Android
將「MarketoActivity」新增至應用程式標籤內的AndroidManifest.xml
檔案。
<activity android:name="com.marketo.MarketoActivity" android:configChanges="orientation|screenSize" android:exported="true">
<intent-filter android:label="MarketoActivity">
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:host="add_test_device" android:scheme="mkto"/>
</intent-filter/>
</activity/>
iOS
-
選取「專案>目標>資訊> URL型別」。
-
新增識別碼: $
-
設定URL配置:
mkto-<S_ecret Key_>
-
包含
application:openURL:sourceApplication:annotation:
至AppDelegate.m
檔案(Objective-C)
iOS — 處理AppDelegate 中的自訂Url型別/深層連結
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary *)options{
return [[Marketo sharedInstance] application:app
openURL:url
options:options];
}
從javascript呼叫API時,會使用這些常數。 您必須建立常數檔案並新增下列內容。
// Lead attributes.
static NSString *const KEY_FIRST_NAME = @"firstName";
static NSString *const KEY_LAST_NAME = @"lastName";
static NSString *const KEY_ADDRESS = @"address";
static NSString *const KEY_CITY = @"city";
static NSString *const KEY_STATE = @"state";
static NSString *const KEY_COUNTRY = @"country";
static NSString *const KEY_GENDER = @"gender";
static NSString *const KEY_EMAIL = @"email";
static NSString *const KEY_TWITTER = @"twitterId";
static NSString *const KEY_FACEBOOK = @"facebookId";
static NSString *const KEY_LINKEDIN = @"linkedinId";
static NSString *const KEY_LEAD_SOURCE = @"leadSource";
static NSString *const KEY_BIRTHDAY = @"dateOfBirth";
static NSString *const KEY_FACEBOOK_PROFILE_URL = @"facebookProfileURL";
static NSString *const KEY_FACEBOOK_PROFILE_PIC = @"facebookPhotoURL";
// Custom actions
static NSString *const KEY_ACTION_TYPE = @"actionType";
static NSString *const KEY_ACTION_DETAILS = @"actionDetails";
static NSString *const KEY_ACTION_LENGTH = @"setLength";
static NSString *const KEY_ACTION_METRIC = @"setMetric";
//Secure Signature
static NSString *const KEY_ACCESSKEY = @"accessKey";
static NSString *const KEY_SIGNATURE = @"signature";
static NSString *const KEY_TIMESTAMP = @"timeStamp";
使用範例
//You can create a Marketo Lead by calling the associateLead function.
RNMarketoModule.associateLead({ email: "", firstName: "", lastName:"", city:""})