When email is sent from Sailthru Email Manager, we go through the links in the templates, and then replace them with redirects, with domains of your choosing, generally something in the form of http://link.yourdomain.com. This allows us to track tap-through metrics on emails and measure your success. For example. Sailthru maintains a fake online clothing store, Varick and Vandam, as a demonstrator platform. Links in emails from V+V will look something like this: http://link.varickandvandam.com/click/13071627.1/aHR0cHM.....

but will redirect to: https://varickandvandam.com/products/1085431

In combination with Universal Links, the Sailthru Mobile SDK can be configured to handle these links and to open your app whenever a certain type of link is clicked.

Make sure you've followed the steps in the Sailthru Docs before starting this guide - it corresponds to the "Link Parsing and Tracking" section.

Handling Universal Links From a Sailthru Email

To properly handle Universal Links, your app will need to implement the UIApplicationDelegate:application:continueUserActivity:restorationHandler: method in its AppDelegate. When an app is opened with a Universal Link, this method is called with an instance of NSUserActivity, which will have a the URL the user clicked on as its webpageURL property. With this knowledge in mind, we can implement this method:

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
    let routingURL;
    if let incomingURL = userActivity.webpageURL {
        if incomingURL.host! == "link.yourdomain.com" { // It's a Sailthru link, so we'll have to decode it
            routingURL = Carnival.handleSailthruLink(incomingURL)
        } else { // We can handle this one without calling Carnival
            routingURL = incomingURL

        routeToViewForURL(incomingURL) // Go to the correct view in the app for the content tapped on
        return true
    return false;
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler {
    NSURL *routingURL;
    if ([continueUserActivity webpageURL] != nil) {
        NSURL *incomingURL = [continueUserActivity webpageURL];
        if ([[incomingURL host] isEqualToString:@"link.yourdomain.com"]) {
            routingURL = [Carnival handleSailthruLink:incomingURL];
        } else {
            routingURL = incomingURL;
        [self routeToViewForURL:routingURL];
        return true;
    return false;

Note that the method routeToViewForURL is just a placeholder, as different apps will have different ways of parsing web URLs into App views.

Calling this Carnival:handleSailthruLink method does two things:

  1. Takes the encoded link.yourdomain.com/click/... link and returns its redirect destination - the link that was entered into the template on Sailthru.
  2. Pings the link domain using NSURLConnection, meaning that tapthrough analytics will be preserved on the Sailthru platform.


At this time, links from Sailthru come in HTTP scheme by default, and internally, the Sailthru Mobile SDK uses NSURLSession to query them when pinging the link.yourdomain.com/click/... link. Unfortunately, this means that for the time being, you'll have to add an ATS exception for your domain. You can do this in your Info.plist file as below:


The K/V Structure in the Info.plist defining ATS Exception behaviour

Or, in XML form:

<!-- At the top level of the Info.plist file  -->

We're looking to have Sailthru links using HTTPS by default as soon as possible.