The latest iOS SDK version is 3.7.3.
What is the Emarsys SDK?
The Emarsys SDK enables you to uses Mobile Engage in a very straightforward way. By incorporating the SDK in your app, we support you, among other things, in handling credentials, API calls, tracking of opens and events as well as logins and logouts in the app.
The Emarsys SDK is open sourced to enhance transparency and to remove privacy concerns. This also means that you can always be up-to-date with what we are working on.
Using the SDK is also beneficial from the product aspect: it simply makes it much easier to send push messages through your app. You do not have to follow and implement changes in our API calls, endpoints and parameters: we do it for you in the SDK. Your only task is to use the latest version of the SDK in your app and we take care of everything else.
Capture explicit consent for data tracking and collection
Before you use iOS SDK you must make sure to capture explicit consent before tracking and collecting data.
It is your responsibility to ensure that you always obtain the necessary consent for that data from your consumers (i.e: a natural person such as a customer, contact, or account). You will find further details on what is automatically tracked by the Emarsys SDK's and what can be manually tracked here.
Integrating with iOS
Video Tutorial
In the video below, an Emarsys Mobile Engineer walks through the standard installation of the Emarsys iOS SDK on a mobile app.
1. Requirements
- The iOS target should be iOS 11 or higher.
- Emarsys App code, which is generated when the app is added to the account.
- Emarsys Predict Merchant ID (If the Predict feature is enabled on the Emarsys account).
Wherever you see <TargetName> or anything similar in <> brackets, you should change those according to your own naming convention.
The Emarsys iOS SDK uses keychain to store data in a secure way. By default, Emarsys iOS SDK uses the keychain of the host application.
If you want to share any data (e.g. hardwareID) between your applications then it is crucial to set the priority of the accessGroups properly in the Keychain Sharing capabilities of your application. For more information, see Add Keychain Sharing capability to the desired target in XCode.
2. Installation
3. Initialization
To configure the SDK, the following has to be done in the AppDelegate
of the application:
ApplicationCode: is needed if you want to use Mobile Engage features.
MerchantId: is needed if you want to use Predict features.
If you want to share hardwareID
between your applications that use Emarsys SDK, additional steps are required. 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 setMerchantId:<merchantId: NSString>];
[builder enableConsoleLogLevels:@[<EMSLogLevel.trace, EMSLogLevel.debug, EMSLogLevel.info, EMSLogLevel.warn, EMSLogLevel.error, EMSLogLevel.basic>]];
}];
[Emarsys setupWithConfig:config];
// Handle push
UNUserNotificationCenter.currentNotificationCenter.delegate = [Emarsys push];
return YES;
}
Swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let config = EMSConfig.make { builder in
builder.setMobileEngageApplicationCode(<applicationCode: String>)
builder.setMerchantId(<merchantId: String>)
builder.enableConsoleLogLevels([<EMSLogLevel.trace, EMSLogLevel.debug, EMSLogLevel.info, EMSLogLevel.warn, EMSLogLevel.error, EMSLogLevel.basic>])
}
Emarsys.setup(config: config)
// Handle push
UNUserNotificationCenter.current().delegate = Emarsys.push
return true
}
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)
}
To track whether the push messages have been opened, the trackMessageOpen
function 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)
}
4. Contact Management
The setContactFieldId
should not be set to 3 (email). In order to prevent your customers' personal data (PII) being stored in our cloud infrastructure, we require use of unique, non-guessable and immutable contact identifiers. Customer ID's are considered secure. Salted email hash is no longer supported for new Mobile Engage implementations. To make sure the behavioural tracking is cross devices (i.e. mobile and web), the Web Extend contact ID should also use Customer ID and match that used on mobile.
4.1. Identifying Contacts
When the application setup is finished, you can use the 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.
The setContact
call only has to be placed once to connect the device to the contact record in Emarsys. It does not need to be placed for every time the app starts. However, if the contact has been logged out using the clearContact
method, the setContact
call should be placed the next time the contact logs into the account to reconnect the device with the contact record.
Objective-C
[[Emarsys setContactWithContactFieldId:<contactFieldId: NSNumber>
contactFieldValue:<contactFieldValue: NSString>
completionBlock:^(NSError *error) {
}];
Swift
Emarsys.setContact(<contactFieldId:NSNumber>, <contactFieldValue: String>) { error in
}
4.2. Clear Contacts
Use the clearContact
method to remove the device details from the contact record, for example, if the user signs out of the app, and they should not receive personalised messages.
Objective-C
[Emarsys clearContactWithCompletionBlock:^(NSError *error) {
}];
Swift
Emarsys.clearContact { error in}
4.3. Clear Push Token
Use the clearPushToken
method to remove the push token of the contact.
Objective-C
[Emarsys.push clearPushTokenWithCompletionBlock:^(NSError *error) {
}];
Swift
Emarsys.push.clearPushToken { error in}
When the application setup is finished, you can use the setContactWithContactFieldValue
to identify the user.
5. Tracking Predict Events
Events are a powerful tool to allow marketers to automate user journeys. Therefore, implementing events on any key user milestone within the app mitigates the need for future ad-hoc development requests to satisfy new marketing contact journeys.
Predict tracking needs to be enabled on the Emarsys account to utilise Predict mobile tracking.
5.1. Track Predict Cart Events
When a contact adds items to the cart, the contents of the cart can be tracked by using the trackCart
method.
cartItems
parameter name has been simplified to items
.
Objective-C
- (void)trackCartWithCartItems:(NSArray<id <EMSCartItemProtocol>> *)cartItems;
--->
- (void)trackCartWithCartItems:(NSArray<id <EMSCartItemProtocol>> *)items;
Swift
We renamed most of our methods on our Swift API to improve the usage of the SDK. XCode can fix most of the changes, but these 2 cases need extra work.
Emarsys.trackCustomEvent(<withName: String>, <eventAttributes: [String:String]?>) { error in
}
--->
Emarsys.trackCustomEvent(<eventName: String>, <eventAttributes: [String:String]?>) { error in
}
Emarsys.predict.trackCategoryView(<withCategoryPath: String>)
--->
Emarsys.predict.trackCategory(<categoryPath: String>)
5.2. Track Predict Purchase Events
When a contact makes a purchase, the purchase can be tracked by using the trackPurchase
method. It is required to include the orderId
parameter when calling this method.
Objective-C
[Emarsys.predict trackPurchaseWithOrderId:<orderId: NSString>
items:<cartItems: NSArray<EMSCartItem *> *>];
Swift
Emarsys.predict.trackPurchase(withOrderId: <orderId: String>, items: <cartItems: Array<EMSCartItem>>)
5.3. Track Predict Item Views
When a contact views an item, the view can be tracked by using the trackItemView
method. It is required to include the itemId
parameter when calling this method.
Objective-C
[Emarsys.predict trackItemViewWithItemId:<itemId: NSString>];
Swift
Emarsys.predict.trackItemView(withItemId: <itemId: String>)
5.4. Track Predict Category Views
When a contact views a category, the category view can be tracked by using the trackCategoryView
method.
Objective-C
[Emarsys.predict trackCategoryViewWithCategoryPath:<categoryPath: NSString>];
Swift
Emarsys.predict.trackCategoryView(withCategoryPath:<categoryPath: String>)
The categoryPath
is required to exactly match that of the product catalogue
5.5. Track Predict Search Term
When a contact enters a search term, the search term can be tracked by using the trackSearchTerm
method.
Objective-C
[Emarsys.predict trackSearchWithSearchTerm:<searchTerm: NSString>];
Swift
Emarsys.predict.trackSearchTerm(withSearchTerm: <searchTerm: String>)
5.6. Track Predict Custom Tag
Use the trackTag
method to track custom tags. The eventName
parameter is required, though the attributes are optional.
Objective-C
[Emarsys.predict trackTag:<tag: NSString>
withAttributes:<attributes: NSDictionary<NSString, NSString>];
Swift
Emarsys.predict.trackTag(<tag: String>, withAttributes: <attributes: [String: String]?>)
6. Tracking Custom Events
Custom events cannot be deleted and therefore should not contain any PII data
Use the trackCustomEvent
method to track custom events. When implementing, the eventName
parameter is required, though the attributes are optional.
Objective-C
[Emarsys trackCustomEventWithName:<eventName: String>
eventAttributes:<eventAttributes: NSDictionary<String, String>
completionBlock:^(NSError *error) {
}];
Swift
Emarsys.trackCustomEvent(<eventName: String>, <eventAttributes: [String:String]?>) { error in
}
7. In-app
7.1. Pause In-app campaigns
When a critical contact activity starts, use pause to stop any disruptions in the user journey by pausing In-app messages. The most common utilisation of the pause
method is on the payment wall.
Objective-C
[Emarsys.inApp pause];
Swift
Emarsys.inApp.pause()
When you issue the pause
command, triggers for In-app messages get ignored. If you want them to be delivered, they must be resent after the resume
command is given.
7.2. Resume In-app campaigns
When the contact is no longer engaging with a critical activity, and In-app messages should resume after a pause, use the resume
method.
Objective-C
[Emarsys.inApp resume];
Swift
Emarsys.inApp.resume()
7.3. React to In-app message triggered event
To react to an event triggered by the In-app message, you can register for it using the setEventHandler
method. The eventHandler
is a callback for an In-app message event.
We had mixed usage of eventHandlersProtocols
and blocks previously in Emarsys SDK, but from version 3.0.0 we changed all handlers to blocks, which will improve the usage from Swift.
This means that we removed EMSEventHandler
from the SDK completely.
Objective-C
Emarsys.inApp.eventHandler = ^(NSString *eventName, NSDictionary<NSString *, id> *payload) {
};
Or
[Emarsys.inApp setEventHandler:^(NSString *eventName, NSDictionary<NSString *, id> *payload) {
}];
Swift
Emarsys.inApp.eventHandler = { name, payload in
}
7.4. 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.
7.4.1. Implementing Inline In-app
There are three ways to implement the inline In-app.
- First option is from XML, this way onAppEventListener, onCompletionListener and onCloseListener cannot be set.
- Secondly is completely from code, this way it could be set up by its constructor.
- The last one is the mixed setup, for this the view could be created in XML, then the listeners should be set by code.
7.4.2. Loading Inline In-app
In order to load the inline In-app, the loadInAppWithViewId
must be called with the corresponding viewId
. When the view is created from 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")
7.4.3. React to Inline In-app event
In order to react to an event triggered from the In-app message, 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
...
}
7.4.4. Inline on completion block
The completionBlock
is triggered when the inline In-app message is loaded.
Objective-C
inlineInApp.completionBlock = ^(NSError *error) {
...
};
Swift
inlineInApp.completionBlock = { error in
...
}
7.4.5. Inline on close block
The closeBlock is triggered when the close button has been clicked in the inline In-app message.
Objective-C
inlineInApp.closeBlock = ^{
...
};
Swift
inlineInApp.closeBlock = {
...
}
8. Rich Push Notifications
Push notification could show media content and action buttons besides the title and body. Push notifications with these types of contents are called Rich Notifications.
Requirements
- Mobile Engage backend is setup for sending push notifications already
- application is setup for receiving push notifications already
- use Emarsys SDK notification extension as mentioned in documentation
Only HTTPS image URLs are supported.
- Add a new Notification Service Extension target to your project.
- Add the
EmarsysNotificationService
to this target in the Podfile.
target "Emarsys Sample" do
pod 'EmarsysSDK'
end
target "NotificationService" do
pod 'EmarsysNotificationService'
end
- Install pods with the pod install command in the workspace directory via terminal.
- If your selected language is Swift, then create a Bridging-Header for your new target.
<NameOfYourExtension-Bridging-Header.h>
#import <EmarsysNotificationService/EMSNotificationService.h>
- Open the NotificationService class in the target, then:
- Import the
EmarsysNotificationService.
- Extend the class
EMSNotificationService
instead ofUNNotificationServiceExtension.
- Import the
import EmarsysNotificationService
class NotificationService: EMSNotificationService {
}
- Set Emarsys event handler in the AppDelegate
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
...
Emarsys.setup(with: config)
// Set the delegates for in-app and push messages after Emarsys configuration in didFinishLaunchingWithOptions.
UNUserNotificationCenter.current().delegate = Emarsys.push
let eventHandler = { name, payload in
// Rich push with actions sent through Emarsys platform will be handled by this method. Ex: Deep link
}
Emarsys.push.notificationEventHandler = eventHandler
Emarsys.push.silentMessageEventHandler = eventHandler
...
return true
}
...
}
9. Switch applicationCode, merchantId and contactFieldId
To allow for the switching of accounts, the Emarsys SDK now includes functions to either set, switch or remove the application code, merchant ID (use for Predict tracking and recommendations) and the contact field ID. The functions do not require a session restart, and common use case would include switching between Emarsys accounts.
9.1. Change Application Code
changeApplicationCode:contactFieldId
and changeApplicationCode:contactFieldId:completionBlock
method has been removed.
changeApplicationCode
has been simplified by removing the methods with contactFieldId
. contactFieldId
is now part of setContact
.
The SDK should be initialized with the new application code when the app starts next time.
The SDK will call clearPushToken
and clearContact
for the old application code automatically. You should call setPushToken
and setContact
when necessary for the new application code in the completion block.
Objective-C
[Emarsys.config changeApplicationCode:code
completionBlock:^(NSError *error) {
if (error == nil) {
[Emarsys.push setPushToken:token];
if (contactIsLoggedIn) {
[Emarsys setContactWithContactFieldId:fieldId
contactFieldValue:fieldValue];
}
}
}];
Swift
Emarsys.config.changeApplicationCode(applicationCode: code) { (error) in
if error == nil {
Emarsys.push.setPushToken(pushToken: token)
if (contactIsLoggedIn) {
Emarsys.setContact(contactFieldId: fieldId, contactFieldValue: fieldValue)
}
}
}
9.2. Change Predict Merchant ID
Objective-C
[Emarsys.config changeMerchantId:<merchantId: NSString>];
Swift
Emarsys.config.changeMerchantId(<merchantId: String>)
10. Retrieve Device Settings
The Emarsys config function allows the retrieval of current SDK configuration. This includes:
- Application Code
- Merchant ID
- Contact ID
- Hardware ID
- Language
- Notification Settings
10.1. Get Application Code
Objective-C
[Emarsys.config applicationCode];
Swift
Emarsys.config.applicationCode()
10.2. Get Merchant ID
Objective-C
[Emarsys.config merchantId];
Swift
Emarsys.config.merchantId()
10.3. Get Contact Field ID
Objective-C
[Emarsys.config contactFieldId];
Swift
Emarsys.config.contactFieldId()
10.4. Get Hardware ID
Objective-C
[Emarsys.config hardwareId];
Swift
Emarsys.config.hardwareId
10.5. Get Language
Objective-C
[Emarsys.config language];
Swift
Emarsys.config.language
10.6. Get Notification Settings
Objective-C
[Emarsys.config notificationSettings];
Swift
Emarsys.config.notificationSettings
11. Inbox Notifications
Emarsys only provides the payload with the messages. The customer’s development team is responsible for building the inbox UI. For more information on Inbox payloads, see Payload examples.
11.1. Fetch Messages
To retrieve the Inbox messages for a contact, 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)")
}
}
11.2. Message Tag
Tags are to be used to set the status of the inbox message, e.g. opened, seen etc. There are 6 tags in total and the details are confirmed in the table below. App developers can add the tags seen, opened, pinned and deleted. It is important to note all the tags though as they will be included in the message payload in the SDK Tag field. Depending on the tag included in the message, the message could be handled differently by the app. An example would be that messages tagged with "high" (for High Priority) could be visible flagged/highlighted by the contact.
Only the tags specified below are supported. Any custom tags created will not work.
Tag Name |
Tag | Description |
Where it can be added |
---|---|---|---|
High Priority | high | Marketer setting of high priority message You can activate this tag from your inbox-campaign by ticking the relevant checkbox. Your developers have to graphically represent this setting in the app inbox. |
Emarsys UI |
Cancelled | cancelled | Marketer cancelled the message This tag is automatically added to your inbox campaign when you recall it. |
Emarsys UI |
Seen | Seen | Inbox messages visible in the app inbox but not opened | Mobile App via the SDK |
Opened | opened | Messages opened on the app | Mobile App via the SDK |
Pinned | pinned | Messages that are pinned as favourite by the contact | Mobile App via the SDK |
Deleted | deleted | Messages that are deleted in the app UI | Both Emarsys UI and/or Mobile App via the SDK |
11.2.1. Add Message Tag
To add a message tag, use the addTag
method.
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)")
}
}
11.2.2. Remove Message Tag
To remove a message tag, use the 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)")
}
}
Verifying the SDK
You can check whether the SDK calls have been received by our servers by clicking the SDK events icon on the Apps tab of the Mobile Engage user interface.
The Name column shows the event that has been received, while the Status column shows the response code. If this value is 201 or 202, then the integration of your SDK has been successful.
Frequently Asked Questions
SDK updates
Why is it beneficial to update the SDK?
Each new release of the SDK brings either new features or fixes known issues, so it is always beneficial to update to the newest version.
We are working hard to ensure the SDK is of the highest quality, and this includes taking backwards compatibility very seriously.
How often should you update to the newest SDK?
In general, you should update your version as often as you can. Even if you are not planning to incorporate new features into your app, we still encourage you to at least update when a new patch version comes out, so you will not miss the bug fixes and other enhancements in the SDK.
What is the version numbering of the SDK?
The SDK versioning follows the x.y.z pattern, where x is the major version, y is the minor version and z is the patch version.
- Major version - This brings a significant release online, such as a long-awaited new feature. Although it is against our intentions, it may happen that a new major version may affect backwards compatibility with the previous release. We strive to keep this to a minimum and do so only with a solid reason for it. This will always be duly communicated beforehand.
- Minor version - This brings smaller new features. Minor versions never break backwards compatibility.
- Patch version - This brings bugfixes, stability and performance enhancements. Patch versions never break backwards compatibility, either.
I have the push token in string format, but the Mobile Engage SDK requires it in NSData format. How can I pass the push token?
If you have a native application, you can normally get the push token in its original form (NSData) in your application's AppDelegate:
didRegisterForRemoteNotificationsWithDeviceToken: method
If you have no way of obtaining it in its original format, you can use Apple's solution to create NSData from hexString: