Latest 2.0.1
Homepage https://github.com/optimove-tech/iOS-SDK-Integration-Guide
License MIT
Platforms ios 10.0
Frameworks UserNotifications, UIKit
Authors

Change Log v2.0 – April 2019

PLEASE READ new iOS change log v2.0

Introduction

Marketers use the Optimove Relationship Marketing Hub to automate the execution of highly-personalized customer communications. Optimove offers its clients an efficient way to report data from their websites and trigger campaigns accordingly.

This guide will show you how to setup the iOS (Swift) SDK in order to:

  • Track visitor and customer actions and events
  • Trigger Realtime campaigns

To implement iOS SDK using Objective-C, go here.

Basic Setup

Request a Mobile SDK from Optimove

Before implementing the Optimove Track & Trigger to track visitor / customer activities or perform other functions (Optipush), you will need to contact your Optimove Customer Success Manager (CSM) or Optimove point of contact.
To get started, please follow these instructions:

1. Pre-requisites

  1. You have a paid development account for your iOS app, and valid certificates for remote notifications or APN Auth key.
  2. The app’s Deployment Target is at least iOS 10.0
  3. Your Cocoapods version is 1.5 or above
  4. If you are already using Firebase in your current application, please make sure to use Firebase version of 5.9.0 (Optimove SDK is dependent on Firebase version 5.9.0)

2. Provide your iOS app details:

Send the following information to your CSM or Optimove POC with your request for your Mobile SDK configuration details in order to incorporate into your iOS app :

  1. Auth key (with its key id) P8 format
  2. Bundle ID (If you are using multiple apps for development/testing purposes, please provide a list of all bundle IDs being used for all environments.)
  3. Team ID (from apple developer dashboard)
  4. App Store ID (from itunesconnect)

3. Retrieve OptimoveTenantInfo details:

After providing the info above, you will receive a OptimoveTenantInfo from the Optimove Product Integration Team that contains:

  1. End-point URL – The URL where the tenant configurations reside
  2. Unique Optimove token – The actual token, unique per tenant
  3. Configuration name – The version of the desired configuration

For a demo application containing the iOS SDK, please use our iOS GitHub repository.

Setting up the iOS SDK

1. Install the SDK

In your Application Target Capabilities:

  1. Enable push notifications capabilities
  2. Enableremote notifications capabilities inBackground Modes

apple_dashboared.png

2. Download OptimoveSDK pod

In order to work with the Optimove SDK for your iOS native app, need to download its module from CocoaPods.

  1. In your Podfile, add the following:

pod 'OptimoveSDK','1.2.3'

Example:

platform :ios, '10.0'

target 'iOSDemo' do
  use_frameworks!

  pod 'OptimoveSDK','1.2.3'
end
  1. OptimoveSDK relies on other modules as infrastructure, such as Firebase, so when you download OptimoveSDK you get the following frameworks:
  • Firebase/Core version 5.9.0
  • Firebase/Messaging
  • Firebase/DynamicLinks

3. If you are using Optipush, see additional configurations here

4. Run the SDK

In your AppDelegate class, inside the callback
application (_: didFinishLaunchingWithOptions:) method, create a new OptimoveTenantInfo object. This object should contain:

  1. The end-point URL
  2. Unique Optimove token
  3. The configuration version provided by the Optimove Integration Team
  4. Indication for existing Firebase module inside your application
  5. Indication for using your own Firebase/Messaging

Use this object as an argument for the SDK function,

  Optimove.sharedInstance.configure(info:)

This call initializes the OptimoveSDK singleton.

  1. You should register for notification certificate from APNs using UIApplication.shared.registerForRemoteNotifications()

Note: It is necessary to import OptimoveSDK in any file that uses OptimoveSDK API

For example:

import UIKit
import UserNotifications
import OptimoveSDK

@UIApplicationMain
class AppDelegate: UIResponder,
UIApplicationDelegate,
UNUserNotificationCenterDelegate
{
var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Intialize the Optimove SDK
    let info = OptimoveTenantInfo(url: "https://optimove.mobile.demo",
          token: "abcdefg12345678",
          version: "myapp.ios.1.0.0",
          hasFirebase: false,
          useFirebaseMessaging: false)
    Optimove.sharedInstance.configure(for: info)

    // Notify the OS that the app needs to receive an APNs token
    UIApplication.shared.registerForRemoteNotifications()

    return true
    }
}

Note : The initialization must be called as soon as possible, unless you have your own Firebase SDK. In this case, call Optimove.configure(info:) right after calling FirebaseApp.configure().

Still in AppDelegate, please implement the following callbacks:

// Called when the OS generates an APNs token
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
{
    // Forward the callback to the Optimove SDK
    Optimove.sharedInstance.application(didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)
}

// Called when a push message is received by the OS and forwarded to the app's process (used for Optimove analytical purposes)
func application(_ application: UIApplication,
        didReceiveRemoteNotification userInfo: [AnyHashable : Any],
        fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)
{
    // Forward the callback to the Optimove SDK 
    if !Optimove.sharedInstance.didReceiveRemoteNotification(userInfo: userInfo,didComplete: completionHandler)
    {
        // The push message was not targeted for Optimove SDK. Implement your logic here or leave as is. 
        completionHandler(.noData)
    }
}

Forward Firebase Tokens to Optimove

Skip this version if your app does not implement a Firebase MessagingDelegate
When the hosting app implements Firebase’s MessagingDelegate it must do 2 things:

  1. Pass true in the useFirebaseMessaging property of the TenantInfo object that is passed to the Optimove.sharedInstance.configure(info:) method.
  2. Forward the messaging(_:didReceiveRegistrationToken:) callback to the Optimove SDK via the Optimove.sharedInstance.optimove(didReceiveFirebaseRegistrationToken:) method.
    Race Condition Warning
    The messaging(_:didReceiveRegistrationToken:) callback is called once when the token is refreshed or initially generated. If this callback is called before the OptimoveSDK has had finished its initialization, the SDK won’t have a way of knowing a new token was generated by Firebase until the next run. To solve this we highly recommend implementing a dedicated class that conforms to the MessagingDelegate protocol, and registers itself as a listener to Optimove’s initialization callback.
    For example:
import Firebase
import OptimoveSDK
class MessagingImplementer:NSObject,OptimoveSuccessStateListener,MessagingDelegate {
    private var fcmToken = ""
    override init() {
        super.init()
        // Register as the FirebaseMessaging delegate once the object is initialized
        Messaging.messaging().delegate = self
    }
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
        self.fcmToken = fcmToken
        // Only when Firebase has successfully generated a token, register as an Optimove State Listener, thus solving the race condition issue
        Optimove.sharedInstance.registerSuccessStateListener(self)
        // Continue with app logic here
    }
    func optimove(_ optimove: Optimove, didBecomeActiveWithMissingPermissions missingPermissions: [OptimoveDeviceRequirement]) {
        // Optimove AND Firebase have both initialized successfully, forward the call safely to Optimove
        Optimove.sharedInstance.optimove(didReceiveFirebaseRegistrationToken: self.fcmToken)
        // Unregister the listener to release the reference that the SDK holds and prevent a memory leak
        Optimove.sharedInstance.unregisterSuccessStateListener(self)
    }
}

5. Important Installation and Usage Notes

The SDK initialization process occurs asynchronously, off the Main Thread.

Before calling the Public API methods, make sure that the SDK has finished initialization by calling the registerSuccessStateListener(listener:) method with an instance of OptimoveSuccessStateListener.

When the SDK has finished its initialization process, the callback optimove(_:didBecomeActiveWithMissingPermissions:) is executed with any missing permissions that the SDK would require to operate optimally.

6. Tracking Visitor and Customer activity

You will also need to include the following steps to complete the basic setup:

  • Tracking User Activities and Events
  • Stitching App Visitors to Registered Customer IDs

    Note: Optimove collects the IDFA for tracking purposes. When submitting to the app store, if asked "Does this app use the Advertising Identifier (IDFA)?", choose ‘Yes’ and make sure to check the folllowing 3 boxes:

    1. “Attribute this app installation to a previously served advertisement”
    2. “Attribute an action taken within this app to a previously served advertisement”
    3. “I, YOUR_NAME, confirm that this app, and any third party…”

    You should not check the box labeled “Serve advertisements within the app” unless you are actually going to display ads.

Advanced Setup

Use the Advanced Setup (optional) in order to track visitor and customer customized actions and events.
As described in Tracking Custom Events, this step requires collaboration between you and Optimove’s Product Integration Team. Please contact your Optimove Customer Success Manager (CSM) or Optimove point of contact to schedule a meeting with the Product Integration team.

Note: You can deploy the basic setup, followed by adding the advanced setup at a later stage. The Basic Setup is a pre-requisite.

Track

Stitching App Visitors to Registered Customer IDs

Once the user has downloaded the application and the Optimove SDK run for the first time, the user is considered a Visitor, i.e. unidentified user

Once the user has authenticated and become identified by a known PublicCustomerId, then the user is considered a Customer.

As soon as this happens for each individual user, call the following method with the newly acquired CustomerId:

Optimove.sharedInstance.set(userId:)

Notes:

  • The CustomerId is usually provided by the server application that manages customers, and is the same ID provided to Optimove during the daily customer data transfer.
  • Any userId that does not correspond to your Optimove unique identifier (Customer ID) due to faulty / unrecognized userIds will now be excluded from your customer tracked activity. Therefore please make sure that the userId sent via the userId is a recognizable ID.
  • You may call the set(userId:) method at any time, regardless if the initialization success callback was received
  • If you will be sending encrypted userId, please follow the steps in Reporting encrypted CustomerIDs

Tracking Screen Visits

To track which screens the user has visited in your app, call the following method:

Optimove.sharedInstance.reportScreenVisit(viewControllersIdentifiers:url:category)

The viewControllersIdentifiers argument should include an array that represents the path of ViewControllers to the current screen.
To support more complex view hierarchies, you may also specify a screen URL in the second parameter and give the page a category.

For example:

 override func viewDidAppear(_ animated: Bool)
    {
        super.viewDidAppear(animated)
        Optimove.sharedInstance.reportScreenVisit(viewControllersIdentifiers: ["main","cart"],
            url: URL(string:"http://my.bundle.id/main/cart/pre_checkout")!, // Optional
            category: "Shoes") // Optional
    }

Note: The reportScreenVisit method should only be called after the initialization success callback was received.

Tracking/Updating User Email Addresses

To track a user’s email address, such as when a visitor enters the app and submits a register or subscribe form, call the setUserEmail method to record the address. This is best used when you want to capture realtime email event.

// Call to notify the SDK that the user has a known email address. Can be called regardless of the "setUserId" call.
Optimove.sharedInstance.setUserEmail(email: "[email protected]");

Notes:

  • In instances where you need to set both the visitor’s user ID and email address simultaneously, you should use the registerUser method instead of setUserEmail. This applies to all situations in which a single user action requires you to set both the user ID and email address (e.g., registration, newsletter signup).

Registering the User ID and User Email at the Same Time

In all situations where a single user action requires you to set both the customer ID and email address (e.g., registration, newsletter signup) simultaneously, you should use the registerUser method (instead of calling both setUserId and setUserEmail) to ensure the proper registration of the user in Optimove.

// Convenience method to call both "setUserId" and "setEmail" simultaneously.
Optimove.sharedInstance.registerUser(email: "[email protected]", userId: "a-unique-user-id");

Tracking Custom Events

Optimove clients may use the Optimove Mobile SDK to track specific customer actions and other custom events to Optimove (beyond OOTB events such visits). This data is used for tracking visitor and customer behavior, targeting campaigns to specific visitor and/or customer segments and triggering campaigns based on particular visitor and/or customer actions/events.

Note: While you can always add/change the custom events and parameters at a later date (by speaking with the Optimove Product Integration Team), only the particular custom events that you and the Optimove Product Integration Team have already defined together will be supported by your Optimove site.

How to Track a Custom Event from within your iOS app

Once you and the Optimove Product Integration Team have together defined the custom events supported by your app, the Product Integration Team will implement your particular functions within your Optimove site, while you will be responsible for implementing the OptimoveEvent protocol of the individual events within your app using the appropriate function calls.

The protocol defines 2 properties:

  1. name: String – Declares the custom event’s name
  2. parameters: [String:Any] – Defines the custom event’s parameters.

Custom Event example:

class MyCustomEvent: OptimoveEvent
{
    var name: String
    var parameters: [String:Any]

    init(name: String, parameters: [String:Any])
    {
        self.name = name
        self.parameters = parameters
    }
}

Then send that event through the reportEvent(event:) method of the Optimove singleton.

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    Optimove.sharedInstance.reportEvent(event: MyCustomEvent())
}

Notes:

  • The reportEvent(event:) method should only be called after the initialization success callback was received.
  • As already mentioned, all custom events must be pre-defined in your Tenant configurations by the Optimove Product Integration Team.
  • Reporting of custom events is only supported if you have the basic Mobile SDK setup implemented.
  • Events use snake_case as a naming convention. Separate each word with one underscore character (_) and no spaces. (e.g., Checkout_Completed)

Trigger

Executing via Optimail

Ability to execute campaigns using Optimove’s Optimail email service provider (ESP) add-on product. With Optimail you will be able to:

  • Send HTML email campaigns
  • Set personalized tags (first name, last name, and more)
  • These Tags are retrieved from both your daily data transfer, as well as the SDK events you are tracking.
  • Preview campaign email before sending
  • Send realtime marketing campaigns based on your website SDK activity triggering rules

For more information on how to add Optimail to your account, please contact your CSM or your Optimove point of contact.

Executing via Optimove APIs

You can also trigger Optimove realtime campaigns using Optimove’s APIs:

  • Register listener to receive realtime campaign notifications, please refer to RegisterEventListener (where eventid = 11)
  • To view the realtime execution flow, please refer to Realtime Flow
  • For more information on how to acquire an API key to use Optimove APIs, please request one from your CSM or your Optimove point of contact.

Latest podspec

{
    "name": "OptimoveNotificationServiceExtension",
    "version": "2.0.1",
    "summary": "A notification extension framework for Optimove SDK",
    "description": "This framework is an addition for the main OptimoveSDK in order to handle notifications",
    "homepage": "https://github.com/optimove-tech/iOS-SDK-Integration-Guide",
    "license": {
        "type": "MIT",
        "file": "LICENSE"
    },
    "authors": {
        "[email protected]": "[email protected]"
    },
    "source": {
        "git": "https://github.com/optimove-tech/iOS-SDK-Integration-Guide.git",
        "tag": "2.0.1"
    },
    "platforms": {
        "ios": "10.0"
    },
    "swift_version": "4.2",
    "source_files": "OptimoveNotificationServiceExtension/OptimoveNotificationServiceExtension/Classes/**/*",
    "frameworks": [
        "UserNotifications",
        "UIKit"
    ]
}

Pin It on Pinterest

Share This