Integrate mParticle with Blueshift (iOS)

This article provides information on how to integrate our SDK with mParticle's iOS SDK.

If you use mParticle in your app for data collection, you can integrate our SDK alongside their SDK so that we can capture data from it and send it to our platform. Here are a couple of things that we need as a prerequisite:

  • Blueshift account
  • mParticle account with Blueshift integration enabled
  • mParticle's iOS SDK integrated with your app

Integrate Blueshift's kit with mParticle's SDK

Update your Xcode project's Podfile to include the following dependency on our kit:

target '<Your Target>' do
    pod 'Blueshift-mParticle-Kit'
end

Yes, that’s it! The mParticle core SDK can now detect the blueshift-kit.

Import

Import the following files to access the kit and Blueshift methods:

#import <BlueShiftConfig.h>
#import <MPKitBlueshift.h>
import BlueShift_iOS_SDK
import Blueshift_mParticle_Kit

Rich push notifications

If you integrate our kit with mParticle's SDK, you can send notifications from our platform to your app's users. For information on how to do that, see Push rich notifications to users.

In addition, you need to add below code in theuserNotificationCenter willPresent notification method of AppDelegate to show push notifications when the app is in the foreground state.

// Call MPKitBlueshift handleUserNotificationCenter method on userNotificationCenter willPresentNotification delegate method callback
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
    [MPKitBlueshift handleUserNotificationCenter:center willPresentNotification:notification withCompletionHandler:^(UNNotificationPresentationOptions options){
        completionHandler(options);
    }];
}
// Call MPKitBlueshift method on userNotificationCenter willPresentNotification delegate method callback
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        MPKitBlueshift.handle(center, willPresent: notification, withCompletionHandler: completionHandler)
    }

Blueshift configuration

You can customize how the blueshift-kit works. Create a BlueShiftConfig instance and pass it to the kit with the user notification delegate set.

BlueShiftConfig *config = [BlueShiftConfig config];

[config setUserNotificationDelegate:self];
[MPKitBlueshift setBlueshiftConfig: config];
let config = BlueShiftConfig()

config.userNotificationDelegate = self
MPKitBlueshift.setBlueshiftConfig(config)

For more information on BlueShiftConfig, see Get started with the SDK.

In-app messages

To enable in-app messaging, specify the value of setEnableInAppNotification to YES:

//enable In-App Message
[config setEnableInAppNotification: YES];
//enable In-App Message
config.enableInAppNotification = true

Use the viewDidAppear method to register pages of your app. Once done, unregister these pages to avoid memory leaks.

(void)viewDidAppear {
    [super viewDidAppear];

    [MPKitBlueshift registerForInAppMessage: NSStringFromClass([ViewController class])];
}

(void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    
    [MPKitBlueshift unregisterForInAppMessage];
}
override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        MPKitBlueshift .registerFor(inAppMessage: String(describing: type(of: self)))
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        MPKitBlueshift.unregisterForInAppMessage()
    }

Automatically fetch in-app messages in the background

You can pull in-app messages from our API in the background. To do this, call the following method of our SDK.

[config setInAppBackgroundFetchEnabled: YES];
config.inAppBackgroundFetchEnabled = true

Manually fetch in-app messages in background

By default, the SDK attempts to pull all the pending in-app messages from our API when the apps starts. If you don't want the SDK to call the API, and you want to call the API yourself, enable the manual mode using the method below to disable the automatic background fetch.

[config setInAppManualTriggerEnabled: YES];
config.inAppManualTriggerEnabled = true

If you enable the manual in-app message fetch (and disable the automatic background fetch), use the following method to call the API manually to actually fetch messages.

[MPKitBlueshift fetchInAppNotificationFromAPI:^(){
     } failure:^(NSError *error){
}];
MPKitBlueshift.fetchInAppNotification(fromAPI: {
            //handle success
        }) { (error) in
            //handle failure
        }

To display the in-app messages in manual mode, call the following method:

[MPKitBlueshift displayInAppNotification];
MPKitBlueshift.displayInAppNotification()

Integrate Blueshift's deep links

You can use Blueshift's deep links in the campaigns that you run with us. Blueshift's deep links are usual http/https URLs that take users to a page in the app if they click on one of them or launch them in a browser. If an email or text message that we send as a part of your campaign contains a Blueshift deep link and a user clicks on it, iOS can launch the app and take the user to the page that is mapped to it.

Prerequisites

Before you get started, there are a couple of things that we need you to do:

  • The Blueshift deep link domain should have a cname record that points to links.getblueshift.com. This is probably done if you have configured email campaigns with us. A valid cname record looks like links.clientdomain.com that points to links.getblueshift.com. Only top-level domains and subdomains are supported at the moment. For example, either clientdomain.com or links.clientdomain.com should point to links.getblueshift.com. We do not support path on a domain such as links.clientdomain.com/repo/folder.
    Reach us on [[email protected]](mailto:[email protected]) if it's not done yet and you want to set it up.
  • Share the Apple App Site Association file with us. Get in touch with your Blueshift account executive on how to do this. For more information on this, see Enabling universal links.
    Here's an example of the Apple App Site Association (AASA) File:
{
    "applinks": {
        "apps": [],
        "details": [{
            "appID": "<Team_id>.<Bundle ID>",
            "paths": [ "/videos/collections/*", 
"NOT /videos/test/2017/*"]
            }]
    }
}

The AASA file is basically a JSON where app ID is the identifier of the application that will handle the Blueshift's deep links and paths are the sections which need to be supported by the app.

Paths in the file can specify if iOS should launch the links in the app or in the browser.

Integration

Before you start configuring the SDK, ensure that
-Associated Domains capability is enabled for your app
-Add your domains to the associated domains capability of your Xcode project

Perform the following steps to do this:

  1. If the Associated Domains capability is not enabled for your app:
    1. Sign in to the Apple Developer Portal, and click on Certificates, Identifiers & Profiles.
    2. On the left navigation panel, choose Identifiers.
    3. Choose your app's identifier on the right-panel under Identfiers.
    4. Enable Associated Domains under Capabilities and click Save.
  2. Now, select your app's project in Xcode's project browser.
  3. Select the right target under the TARGETS and select the Signing & Capabilities tab. If Associated Domains capability is not present under this tab, click + Capability and double click on Associated Domains in the list to add this capability to the target.
  4. Now, click + under the Associated Domains capability to add a new entry. Add the entry as:
    • applinks:<domain name>
      For example, applinks:universallinks.blueshiftreads.com

For example, if links.clientdomain.com is the domain that you have created to handle Blueshift's deep links, provide it here. This is also the domain that is mapped to links.getblueshift.com.

Now, set the BlueshiftUniversalLinksDelegate in the AppDelegate.m or AppDelegate.swift file:

//Set blueshiftUniversalLinks delegate
[config setBlueshiftUniversalLinksDelegate:self];
//Set blueshiftUniversalLinks delegate
config.blueshiftUniversalLinksDelegate = self

The BlueshiftUniversalLinksDelegate has 3 methods:

  • The didStartLinkProcessing method receives a callback that states that the SDK has started processing the Blueshift deep link. You can use this method to show the activity indicator on screen.
  • The didCompleteLinkProcessing(_ url: URL?) method receives the callback if the SDK processes the Blueshift deep link successfully.
  • The didFailLinkProcessingWithError(_ error: Error?, url: URL?) method receives the callback if the SDK fails to process the Blueshift deep link.
@interface AppDelegate : UIResponder <UIApplicationDelegate,  BlueshiftUniversalLinksDelegate>
@property (strong, nonatomic) UIWindow *window;

@end

  
@implementation AppDelegate

//callback to indicate the start of processing of url
-(void)didStartLinkProcessing {
    //show activity indicator
}
 
//Universal link will be received here on successful processing
-(void)didCompleteLinkProcessing:(NSURL *)url {
    //handle success by navigating to the respective screen and hide activity indicator
}
 
//Error will be received here with unprocessed url on unsuccessful processing
-(void)didFailLinkProcessingWithError:(NSError *)error url:(NSURL *)url {
    //Handle failure and hide activity indicator
}
@end
extension AppDelegate: BlueshiftUniversalLinksDelegate {
    
    //callback to indicate the start of processing of url
    func didStartLinkProcessing() {
        //show activity indicator
    }
    
    //Universal link will be received here on successful processing
    func didCompleteLinkProcessing(_ url: URL?) {
        //handle success by navigating to the respective screen and hide activity indicator
    }
    
    //Error will be received here with unprocessed url on unsuccessful processing
    func didFailLinkProcessingWithError(_ error: Error?, url: URL?) {
        //Handle failure and hide activity indicator
    }
}

Call [MPKitBlueshift handleBlueshiftUniversalLinksForURL:url] inside application: continueUserActivity: delegate method of the AppDelegate.m or AppDelegate.swift file.

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
    if ([userActivity.activityType isEqualToString: NSUserActivityTypeBrowsingWeb]) {
        NSURL *url = userActivity.webpageURL;
        [MPKitBlueshift handleBlueshiftUniversalLinksForURL:url];
    }
    return true;
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
        if let url = userActivity.webpageURL {
            MPKitBlueshift.handleUniversalLinks(for: url)
        }
        return true
    }

❗️

Ensure that you replace links.clientdomain.com with the cname-record value that points to links.getblueshift.com.

Troubleshooting

App is not launched if a Blueshift deep link is clicked.

  • Ensure that the user is not pasting the links in the browser. The best way to test the Blueshift's deep links is to open it from an email. You can send a test email with Blueshift's deep links by creating the templates and test campaigns.
  • Ensure that you have your AASA file hosted and it's correct. To check the hosted AASA file, go to
    https://<<yourdomain>>/.well-known/apple-app-site-association.
    For example, https://universallinks.blueshiftreads.com/.well-known/apple-app-site-association.
  • Ensure that you have Associated Domain capability enabled in the XCode project setting, and it has an entry of applinks with your universal links domain.
    For example, applinks:universallinks.blueshift.com.

How to handle the existing Universal Links or Universal Links that do not come from a Blueshift campaign?
Use the helper function isBlueshiftUniversalLinkURL: to identify if the URL is from Blueshift. If it returns true, call handleBlueshiftUniversalLinks(for:url) function and handle the existing universal links or universal links other than Blueshift deep links using an if-else statement. For example:

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity
 restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> *restorableObjects))restorationHandler {
    NSURL *url = userActivity.webpageURL;
    if (url != nil) {
        if ([MPKitBlueshift isBlueshiftUniversalLinkURL:url]) {
            [MPKitBlueshift handleBlueshiftUniversalLinksForURL:url];
        } else {
            	// handle existing Universal links or Universal Links other than Blueshift 
        }
    }
    return YES;
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
        if let url = userActivity.webpageURL {
            if MPKitBlueshift.isBlueshiftUniversalLinkURL(url) {
                MPKitBlueshift.handleUniversalLinks(for: url)
            } else {
                // handle existing Universal links or Universal Links other than Blueshift
            }
        }
        return true
    }

I want a user to launch few URLs in the app, and few in the browser. How do I do that?
In the AASA file, you can specify whether iOS should launch a URL in the app or in the browser. For more information, see this document.

How to support multiple apps using the same universal link domain?
Add your AppID in the AASA file. For more information, see this document.

How to support multiple universal link domains in the same app?
Add your domains to the associated domains capability of your Xcode project. For example:

  • applinks:universallinks.blueshift.com
  • applinks:links.blueshift.com