Skip to content
szabist edited this page Mar 16, 2021 · 57 revisions

Contents

Integrate with EMSAppDelegate

Note

The use of this approach is optional, you can follow the steps below to integrate the SDK.

We created an easier solution to integrate Emarsys SDK by inheriting from our EMSAppDelegate. Find our instructions here

Integrate without EMSAppDelegate

1. First steps

Note

Please complete the required steps before proceeding

A Sample Application using the Emarsys SDK is available here. The Sample Application provides examples of how you can use the various features of the Emarsys SDK in a real application and what steps are needed e.g. to be able to receive push messages.

1.1 Initialization

To configure the SDK, the following has to be done in the AppDelegate of the application:

Note

mobileEngageApplicationCode: is needed if you want to use Mobile Engage features

predictMerchantId: is needed if you want to use Predict features

If you want to share hardware id between applications you use Emarsys SDK in, further steps are requiered. This feature is only available from 2.7.0. For more information please read here

The console logging is only working on DEBUG mode

Our default console logging is only showing logs when you call an unallowed method. You are able to modify the allowed loglevels for console logging, by setting it during the setup.

Objective-C
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    EMSConfig *config = [EMSConfig makeWithBuilder:^(EMSConfigBuilder *builder) {
        [builder setMobileEngageApplicationCode:<applicationCode: NSString>];
        [builder setContactFieldId:<contactFieldId: NSNumber>];
        [builder setMerchantId:<predictMerchantId: NSString>];
        [builder enableConsoleLogLevels:@[<EMSLogLevel.trace, EMSLogLevel.debug, EMSLogLevel.info, EMSLogLevel.warn, EMSLogLevel.error, EMSLogLevel.basic>]];
    }];
    [Emarsys setupWithConfig:config];

    return YES;
}
Swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    let config = EMSConfig.make { builder in
        builder.setMobileEngageApplicationCode(<applicationCode: String>)
        builder.setContactFieldId(<contactFieldId: Number>)
        builder.setMerchantId(<predictMerchantId: String>)
        builder.enableConsoleLogLevels([<EMSLogLevel.trace, EMSLogLevel.debug, EMSLogLevel.info, EMSLogLevel.warn, EMSLogLevel.error, EMSLogLevel.basic>])
    }
    Emarsys.setup(with: config)

    return true
}

1.2 setContact

After application setup is finished, you can use setContact method to identify the user with contactFieldValue.

Without contact identification all tracked events will be linked to an anonymous contact in Mobile Engage and will rely on visitor cookies in case of Predict.

Objective-C
[Emarsys setContactWithContactFieldValue:<contactFieldValue: NSString>
                         completionBlock:^(NSError *error) {
                         }];
Swift
Emarsys.setContactWithContactFieldValue(<contactFieldValue: String>) { error in
}

1.3 setAuthenticatedContact

Note

At the current time Predict does not support authenticating users with Open ID Connect, identifying a contact with setAuthenticatedContact will disable the usage of Predict features!

After the application setup is finished, you can use setAuthenticatedContact method to identify the user with an openIdToken.

More information about Open ID Connect can be found here.

Without contact identification all tracked events will be linked to an anonymous contact in Mobile Engage and will rely on visitor cookies in case of Predict. Please note that openIdToken parameter is required, but the CompletionListener is optional.

Objective-C
[Emarsys setAuthenticatedContactWithIdToken:<idToken: NSString>
                         completionBlock:^(NSError *error) {
                         }];
Swift
Emarsys.setAuthenticatedContactWithIdToken(<idToken: String>) { error in
}
#### 1.4 clearContact
When the user signs out, the `clearContact` method should be used:
> __`Note`__
>
> No need to call `clearContact` every time, even if the user isn't logged in. Just make sure it is called when the user logs out of the application.
###### Objective-C
```objectivec
[Emarsys clearContactWithCompletionBlock:^(NSError *error) {
}];
Swift
Emarsys.clearContact { error in
}

1.5 trackCustomEvent

If you want to track custom events, the trackCustomEvent method should be used, where the eventName parameter is required, but the other attributes are optional.

Objective-C
[Emarsys trackCustomEventWithName:<eventName: String>
                  eventAttributes:<eventAttributes: NSDictionary<String, String>
                  completionBlock:^(NSError *error) {
                  }];
Swift
Emarsys.trackCustomEvent(withName: <eventName: String>, eventAttributes: <eventAttributes: NSDictionary<String, String>) { error in
}

2. Push

2.1 setPushToken

The pushToken has to be set when it arrives:

Objective-C
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    [Emarsys.push setPushToken:deviceToken
               completionBlock:^(NSError *error) {
               }];
}
Swift
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    Emarsys.push.setPushToken(deviceToken) { error in
    }
}

2.2 pushToken

The pushToken value can be retreived by this method

Objective-C
[Emarsys.push pushToken];
Swift
Emarsys.push.pushToken

2.3 clearPushToken

If you want to remove pushToken for the Contact, you can use clearPushToken.

Objective-C
[Emarsys.push clearPushTokenWithCompletionBlock:^(NSError *error) {
}];
Swift
Emarsys.push.clearPushToken { error in
}

2.4 trackMessageOpen

If you want to track whether the push messages have been opened, the trackMessageOpen method should be used. In the simplest case this call will be in the AppDelegate's didReceiveRemoteNotification:fetchCompletionHandler: method:

Objective-C
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    [Emarsys.push trackMessageOpenWithUserInfo:userInfo
                               completionBlock:^(NSError *error) {
                               }];
}
Swift
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    Emarsys.push.trackMessageOpen(userInfo: userInfo) { error in
    }
}

2.5 setSilentMessageEventHandler

In order to react to an event triggered from the silent message, you can register for it using the setSilentMessageEventHandler method. The eventHandler is a callback for silent message event.

Objective-C
[Emarsys.push setSilentMessageEventHandler:<silentMessageEventHandler: id<EMSEventHandler>>];
Swift
Emarsys.push.silentMessageEventHandler = <silentMessageEventHandler: EMSEventHandler>

2.6 handleMessageWithUserInfo

Silent messages arrives in application:didReceivedRemoteNotification:fetchCompletionHandler:, so in order to be able to handle them, call handleMessageWithUserInfo: method there, or inherit your appDelegate from our EMSAppdelegate so we handle it for you.

- (void)         application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
      fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
    [Emarsys.push handleMessageWithUserInfo:userInfo];
    completionHandler(UIBackgroundFetchResultNewData);
}
override func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        Emarsys.push.handleMessage(userInfo: userInfo)
        completionHandler(.newData)
    }

2.7. Use EMSNotificationInformationDelegate

In case you need information about the received message, you can set your EMSNotificationInformationDelegate implementation as a delegate to our Emarsys.push and we will call the method of the delegate with a NotificationInformation object.

Objective-C
Emarsys.push.silentNotificationInformationDelegate = <Your EMSNotificationInformationDelegate implementation>;
Swift
Emarsys.push.silentNotificationInformationDelegate = <Your EMSNotificationInformationDelegate implementation>

3. In-App

3.1 Overlay In-App

A full screen In-App dialog, that hovers in front of the application. Only one can be displayed at a time.

3.1.1 pause

When a critical activity starts and should not be interrupted by In-App, pause In-App messages.

Objective-C
[Emarsys.inApp pause];
Swift
Emarsys.inApp.pause()
3.1.2 resume

In order to show In-App messages after being paused, use the resume method.

Objective-C
[Emarsys.inApp resume];
Swift
Emarsys.inApp.resume()
3.1.3 setEventHandler

In order to react to an event triggered from the In-App message, you can register for it using the setEventHandler method. The eventHandler is a callback for an In-App message event.

Objective-C
[Emarsys.inApp setEventHandler:<eventHandler: id<EMSEventHandler>>];
Swift
Emarsys.inApp.eventHandler = <eventHandler: EMSEventHandler>

3.2 Inline In-App

In-App message, that takes place in the application's view hierarchy. Multiple inline In-App components are allowed in one screen.

Note The Inline In-App feature is still in pilot phase, please only use it if you have a pilot service order in place! If you need help with piloting, please contact your Client Success Manager @ Emarsys.

3.2.1 Implementation

There are three ways to implement the inline In-App.

  • First way is the Interface Builder, this way eventHandler, completionBlock and closeBlock cannot be set.
  • Secondly is fully from code, this way it must be set up with it's init method.
  • The last one is the mixed setup, for this the view must be created through interface builder, then the blocks must be set through code.
3.2.1 loadInAppWithViewId

In order to load the inline In-App, the loadInAppWithViewId must be called with the corresponding viewId. When the view is created from the UI builder and this value has been set, this call is unnecessary.

Objective-C
EMSInlineInAppView *inappView = [[EMSInlineInAppView alloc] initWithFrame:<frame: CGRect>];
[self.inappView loadInAppWithViewId:@"view-id"];
Swift
let inlineInApp = EMSInlineInAppView(<frame: CGRect>)
inlineInApp.loadInApp(withViewId: "view-id")        
3.2.2 eventHandler

In order to react to an event triggered from the In-App message, you can register for it using the setEventHandler method. The eventHandler is a callback for an In-App message event.

Objective-C
inlineInApp.eventHandler = ^(NSString *eventName, NSDictionary<NSString *, NSObject *> *payload) {
    ...
};
Swift
inlineInApp.eventHandler = { name, payload in
    ...
}   
3.2.3 completionBlock

The completionBlock is triggered when the inline In-App message is loaded.

Objective-C
inlineInApp.completionBlock = ^(NSError *error) {
    ...
};
Swift
inlineInApp.completionBlock = { error in
    ...
}   
3.2.4 closeBlock

The closeBlock is triggered when the close button has been clicked in the inline In-App message.

Objective-C
inlineInApp.closeBlock = ^{
    ...
};
Swift
inlineInApp.closeBlock = {
    ...
}   

4. Predict

We won't go into the details to introduce how Predict works, and what its capabilities are, but here we aim to explain the mapping between the Predict commands and our interface. Please visit Predict's documentation for more details.

4.1 Initialization

To use the Predict functionality, you have to setup your merchantId during the initialization of the SDK. In order to track Predict events, you can use the methods available on our Predict interface.

4.2 trackCart

When you want to track the cart items in the basket you can call the trackCart method with a list of CartItems. CartItem is an interface that can be used in your application for your own CartItems and then simply use the same items with the SDK.

Objective-C
[Emarsys.predict trackCartWithCartItems:<cartItems: NSArray<EMSCartItem *> *>];
Swift
Emarsys.predict.trackCart(withCartItems: <cartItems: Array<EMSCartItem>>)

4.3 trackPurchase

To report a purchase event you should call trackPurchase with the items purchased and with an orderId.

Objective-C
[Emarsys.predict trackPurchaseWithOrderId:<orderId: NSString>
                                    items:<cartItems: NSArray<EMSCartItem *> *>];
Swift
Emarsys.predict.trackPurchase(withOrderId: <orderId: String>, items: <cartItems: Array<EMSCartItem>>)

4.4 trackItemView

If an item was viewed use the trackItemView method with an itemId.

Objective-C
[Emarsys.predict trackItemViewWithItemId:<itemId: NSString>];
Swift
Emarsys.predict.trackItemView(withItemId: <itemId: String>)

4.5 trackCategoryView

When the user navigates between the categories you should call trackCategoryView in every navigation. Be aware to send categoryPath in the required format. Please visit Predict's documentation for more information.

Objective-C
[Emarsys.predict trackCategoryViewWithCategoryPath:<categoryPath: NSString>];
Swift
Emarsys.predict.trackCategoryView(withCategoryPath:<categoryPath: String>)

4.6 trackSearchTerm

To report search terms entered by the contact use trackSearchTerm method.

Objective-C
[Emarsys.predict trackSearchWithSearchTerm:<searchTerm: NSString>];
Swift
Emarsys.predict.trackSearch(withSearchTerm: <searchTerm: String>)

4.7 trackTag

To track custom tags, use the trackTag method, where the eventName parameter is required, but the attributes is optional.

Objective-C
[Emarsys.predict trackTag:<tag: NSString>
           withAttributes:<attributes: NSDictionary<NSString, NSString>];
Swift
Emarsys.predict.trackTag(<tag: String>, withAttributes: <attributes: [String: String]?>)

4.8 recommendProducts

With the Emarsys SDK you can ask for product recommendations based on different recommendation logics.

Note

recommendProducts is also going to track the value attached to the logic on the backend, so no additional tracking needed when using recommendations!

4.8.1 recommendationLogic

This is a required parameter of the recommendProducts method. The currently supported logics are:

  • SEARCH - based on searchTerm
  • CART - based on cartItems
  • RELATED - based on itemViewId
  • CATEGORY - based on categoryPath
  • ALSO_BOUGHT - based on itemViewId
  • POPULAR - based on categoryPath
  • PERSONAL - based on current browsing and activity
  • HOME - based on most recent browsing behaviour

Note

For more information of the recommender logics, please visit [the official documentation].(https://help.emarsys.com/hc/en-us/articles/115004662189-Web-Recommender-logics "The Official Documentation")

You can pass the values to the chosen recommendation logic, but if you leave it empty, the SDK handles it and uses the last tracked values.

4.8.2 recommendationFilters

This is an optional parameter of the recommendProducts method. You can filter product recommendations with the SDK by building RecommendationFilters. There are two types of filters: Exclude or Include. In every case there are four types of comparators you can use to compare your chosen field to expectationValue:

  • isValue - checking if the field is matching the value
  • inValues - any of the values has a match with the field
  • hasValue - One of the field values is equal to expectation value (applicable only to fields containing multiple values)
  • overlapsValues - One or more of the field values are found in expectation values (applicable only to fields containing multiple values)

For further information please check the Predict documentation

4.8.3 limit

This is an optional parameter of the recommendProducts method.

You can limit the number of recommended products received by defining a limit. This is an optional parameter, by default it's value is 5.

4.8.4 productsBlock

This is a required parameter of the recommendProducts method.

The SDK is going to retrieve recommended products via it's productsBlock

Objective-C
[Emarsys.predict recommendProductsWithLogic:[EMSLogic searchWithSearchTerm:@"shirt"]
                                                            filters:@[[EMSRecommendationFilter excludeFilterWithField:@"category"
                                                                                                              isValue:@"women"]]
                                                              limit:@10
                                                      productsBlock:^(NSArray<EMSProduct *> *products, NSError *error) {
                                                          if (products) {
                                                              for (EMSProduct *product in products) {
                                                                  NSLog([product description]);
                                                              }
                                                          } else {
                                                              NSLog(error.localizedDescription);
                                                          }
                                                      }];
Swift
Emarsys.predict.recommendProducts(with: EMSLogic.search(withSearchTerm: "shirt"), filters: [EMSRecommendationFilter.excludeFilter(withField: "category", isValue: "women")], limit: 10) { products, error in
            if let products = products {
                for product in products {
                    print("\(product)")
                }
            } else if let error = error {
                print("\(error.localizedDescription)")
            }
        }
4.8.5 availabilityZones

This is an optional parameter of the recommendProducts method.

You can presonalize the recommendation further by setting the availabilityZones parameter of the recommendation, to only recommend the locally available products.

For more information please check the Emarsys Predict documentation

4.9 trackRecommendationClick

The Emarsys SDK doesn't track automatically recommendationClicks, so you have to call manually trackRecommendationClick when an interaction happens with any of the recommended products.

Objective-C
[Emarsys.predict trackRecommendationClick:<product: EMSProduct>];
Swift
Emarsys.predict.trackRecommendationClick(<product: EMSProduct>)

4.10 variants

Variants are used by the HOME and PERSONAL logic types. By adding a list of Strings used as suffixes to logic names, recommendations are grouped by the variants provided.

5. DeepLink

Note

Please check our DeepLink page for more information.

In order to track email link clicks that open the application directly with the Emarsys SDK, you need to call trackDeepLink in your AppDelegate's application:continueUserActivity:restorationHandler: method.

Objective-C
-  (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
  restorationHandler:(void (^)(NSArray *__nullable restorableObjects))restorationHandler {
    return [Emarsys trackDeepLinkWith:userActivity sourceHandler:^(NSString *source) {
        NSLog([NSString stringWithFormat:@"Source url: %@", source]);
    }];
}
Swift
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
    return Emarsys.trackDeepLink(with: userActivity, sourceHandler: { url in
        if let source = url {
            print(source)
        }
    })
}

The (BOOL) return value of Emarsys.trackDeepLink indicates whether the UserActivity contained a Mobile Engage email deep link and whether it was handled by the SDK.

The first parameter is the UserActivity that comes from the AppDelegate’s application:continueUserActivity:restorationHandler: method.

The second parameter is optional, it is a closure/block that provides the source Url that was extracted from the UserActivity.

For more information, read the relevant iOS documentation.

6. ApplicationCode and merchantId change

Emarsys SDK provides a solution for applicationCode and merchantId change in a convenient way without restarting the SDK. Please check our Config page for more information.

7. Inbox

Note

Under Development Please be aware that the Inbox feature is under development and therefore should not be included in any SDK integration at present. We estimate that we will be able to accept pilot clients for this feature by Q3 2020.

7.1 Device Centric Inbox

7.1.1 fetchNotifications

In order to receive the inbox content, you can use the fetchNotifications method.

Objective-C
[Emarsys.inbox fetchNotificationsWithResultBlock:^(EMSNotificationInboxStatus *inboxStatus, NSError *error) {
    if (error) {
        NSLog(error);
    } else {
        NSLog(inboxStatus.notifications);
        NSLog(inboxStatus.badgeCount);
    }
}];
Swift
Emarsys.inbox.fetchNotifications { status, error in
    if let error = error {
        print(error as Any)
    } else if let status = status {
        print("Notifications: \(status.notifications) badgeCount: \(status.badgeCount)")
    }
}

7.1.2 resetBadgeCount

When your user opened the application inbox, you might want to reset the unread count (badge). To do so, you can use the resetBadgeCount method.

Objective-C
[Emarsys.inbox resetBadgeCountWithCompletionBlock:^(NSError *error) {
}];
Swift
Emarsys.inbox.resetBadgeCount { error in
}

7.1.3 trackNotificationOpen

To track the notification opens in inbox, use the following trackNotificationOpen method.

Objective-C
[Emarsys.inbox trackNotificationOpenWithNotification:<notification: EMSNotification>
                                     completionBlock:^(NSError *error) {
}];
Swift
Emarsys.inbox.trackNotificationOpen(with: <notification: EMSNotification>) { error in
}

7.2. MessageInbox

User centric inbox solution.

7.2.1 fetchMessages

In order to receive the messageInbox content, you can use the fetchMessages method.

Objective-C
[Emarsys.messageInbox fetchMessagesWithResultBlock:^(EMSInboxResult *inboxResult, NSError *error) {
    if (error) {
        NSLog(error);
    } else {
        NSLog(inboxResult.messages);
    }
}];
Swift
Emarsys.messageInbox.fetchMessages { inboxResult, error in
    if let error = error {
        print(error as Any)
    } else if let inboxResult = inboxResult {
        print("Messages: \(inboxResult.messages)")
    }
}

7.2.2 addTag

To label a message with a tag, you can use addTag method. (for example: "READ", "SEEN" etc)

Objective-C
[Emarsys.messageInbox addTag:<tag: String>
                      forMessage:<messageId: String>
                 completionBlock:^(NSError *error) {
                        if (error) {
                            NSLog(error);
                        }
                 }];
Swift
Emarsys.messageInbox.addTag(<tag: String>, forMessage:<messageId: String>) { error in
    if let error = error {
        print("Error: \(error.localizedDescription)")
    }
}

7.2.3 removeTag

To remove a label from a message, you can use removeTag method.

Objective-C
[Emarsys.messageInbox removeTag:<tag: String>
                      fromMessage:<messageId: String>
                 completionBlock:^(NSError *error) {
                        if (error) {
                            NSLog(error);
                        }
                 }];
Swift
Emarsys.messageInbox.remove(<tag: String>, fromMessage: <messageId: String>) { error in
    if let error = error {
        print("Error: \(error.localizedDescription)")
    }
}

8. Geofence

PILOT VERSION

Note The Geofence feature is still in pilot phase, please only use it if you have a pilot service order in place! If you need help with piloting, please contact István Szabó, PM of SDK @ Emarsys.

Geofence makes it available to trigger certain actions based on the users location. When the user enters a predefined region (represented by latitude, longitude and radius) EmarsysSDK fires a customEvent which can trigger an action for example a push notification. This requires permission for background locations from the user.

Note

Based on our experiences so far, the accuracy of geofencing is inconsistent and can be different based on device types and the environment of usage. We recommend to use at least 50m of radius, to ensure that the triggers happen. Based on the Apple documentation only 20 geofences/app can be used, so please be aware that our current geofencing solution is only works well when there is no other geofencing solution used in the application.

Requirements

For the location permissions the applications Info.plist must be extended with the following keys:

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>AlwaysUsage is a must have for region monitoring (or some description of your choice)</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>AlwaysUsage is a must have for region monitoring (or some description of your choice)</string>

Make sure that your app is requesting the required permissions from the user. To make it easier, you can call our requestAlwaysAuthorization method.

8.1 enable

The enable method is responsible for the activation of this feature

Objective-C
[Emarsys.geofence enableWithcompletionBlock:^(NSError *error) {
                        if (error) {
                            NSLog(error);
                        }
                 }];
Swift
Emarsys.geofence.enable { error in
    if let error = error {
        print("Error: \(error.localizedDescription)")
    }
}

8.2 disable

The disable method is responsible for disabling this feature

Objective-C
[Emarsys.geofence disable];
Swift
Emarsys.geofence.disable()

8.3 isEnabled

The isEnabled method returns if the geofencing is currently enabled or not

Objective-C
[Emarsys.geofence isEnabled];
Swift
Emarsys.geofence.isEnabled()

8.4 setEventHandler

In order to react to an event triggered by a geofence, you can register for it using the setEventHandler method. The eventHandler is a callback for a Geofence event.

Objective-C
[Emarsys.geofence setEventHandler:<eventHandler: id<EMSEventHandler>>];
Swift
Emarsys.geofence.eventHandler = <eventHandler: EMSEventHandler>

8.5 requestAlwaysAuthorization

The requestAlwaysAuthorization method is responsible for asking the required permissions from the user. Calling this method is not necessary, if your app already asked the user for the permissions.

Objective-C
[Emarsys.geofence requestAlwaysAuthorization];
Swift
Emarsys.geofence.requestAlwaysAuthorization()

9. On Event Action

Emarsys SDK supports a new way of creating actions in the applications by tracking a customEvent, this trigger happens in a silent way, no in-app or push is needed. All of the action types known from rich push messages are supported.

For this to work an eventHandler should be set up in the SDK.

9.1 setEventHandler

Objective-C
[Emarsys.onEventAction setEventHandler:id<EMSEventHandler>];
Swift
Emarsys.onEventAction.eventHandler = <eventHandler: EMSEventHandler>
Clone this wiki locally