Deferred Deep Links – A Complete Walkthrough

This post will take you through a complete implementation example to help you get Onboarding Links (deferred deep links) working in your own app.

Deferred deep links are a powerful way to pass data through an app install, enabling customized onboarding for your brand new users. To learn more about deferred deep links, have a read through the following posts:

Please note, the code samples and sample project are written in Swift using Xcode 6.4. You can download the finished project here: https://github.com/DevMoz/deferred-deep-links

To use Tapstream’s deferred deep links, you’ll need a Tapstream Marketing Pro or Marketing Expert account. Deferred deep links will not work on free plans. If you’d like to speak to an account rep, email support@tapstream.com and someone will reach out directly.

Ok, let’s get started.

Open up Xcode and create a new single view application. Name it whatever you like (you won’t need core data):

Once your project is setup, head on over to main.Storyboard  and select the only view controller in your storyboard:

With the view controller selected, select the ‘Editor’ menu -> embed in -> navigation controller

You should now have the navigation controller as the initial view controller with a segue to the embedded view controller.

Drag a UIWebView onto your view controller

Don’t forget to constrain your webview:

Select the assistant editor and wire up an outlet from your webview to your view controller

@IBOutlet weak var webView: UIWebView!

Close the assistant editor and create a new Cocoa Touch Class file. Make it a subclass of UIViewController and name it OnboardingLinkViewController

Next, go back to main.Storyboard  and drag a new view controller onto the storyboard

Notice the new view controller has no segues to it. Change the new view controller’s class to: OnboardingLinkViewController

You can design your new OnboardingLinkViewController  however you want just make sure to drag a UITextView  and a UIButton  onto it. Here’s how it looks in the included sample project. The UITextView  is the empty space at the top and the UIButton  at the bottom:

Open the assistant editor and connect the UITextView  to an outlet called nameField  and the UIButton  to an action called dismissOnboardingVC

@IBOutlet weak var nameField: UITextView!

Ok, from here on we should be dealing mostly with code. Close the assistant editor and go back to your ViewController.swift file.

Setup viewDidLoad  as follows:

Run your project. You should just see Apple’s homepage displayed.

Now we have the basic project setup. Let’s say that this is your app today…Millions of people are downloading your amazing Apple website browser. Now you want to jazz things up by offering certain new users a personalized experience. Maybe you want to invite some VIP’s into your app and you want to greet them with a special offer that nobody else can see. This is just one of the many possibilities with deferred deep links.

Before you go any further, you’ll need to take a minute to follow the instructions for importing the Tapstream SDK into your project: https://tapstream.com/developer/ios/integration/

Once you’ve imported the files and initialized the SDK, make your App Delegate’s didFinishLaunchingWithOptions  look like:

You can find your app id and SDK secret in the account configuration page accessible from the account settings menu in the Tapstream dashboard:

Run your project to verify the SDK has been succesfully initialized and is communicating with Tapstream. You should see events firing in your output logs:

At the top of your AppDelegate.swift  file, add boolean property called firstRun  and set it to false

var firstRun = false

Next, just below where you’ve initialized the Tapstream SDK in didFinishLaunchingWithOptions , place the following code:

didFinishLaunchingWithOptions should now look like:

Onboarding Links work by hitting the Tapstream timeline lookup API to fetch all of the information we know about a given user. This data includes any custom params sent with the campaign link click. Since we only need to fetch this data once, we use NSUserDefaults  to set a boolean flag that will set firstRun  to true only the very first time the app is run. This isn’t strictly necessary but it will save your app from making needless requests.

We are done with the App Delegate and can now head over to ViewController.swift

At the bottom of the file, add a utility function:

This is just a convenience function for running whatever code we place in the closure after a delay set in seconds. This isn’t needed for deferred deep links and it’s just to make the sample project a little easier to follow when it’s run.

Next, at the bottom of your viewDidLoad , add:

Here we’re just getting hold of the firstRun  boolean we set in the app delegate. If this is the first time the app is run, we’ll wait three seconds (using the utility method just defined), then we call fetchData . We’ll define fetchData  next and it’s where the fun happens. If this isn’t the apps first run, then fetchData  isn’t called.

viewDidLoad  should now look like:

Now you can add the fetchData  method to your ViewController.swift  file:

Let’s break down what’s going on:

1. We instantiate the OnboardingLinksViewController  we created in the storyboard
2. We grab the Tapstream singleton and call getConversionData . This is an asynchronous call to the Tapstream timeline lookup API that will return all of the info we know about the converted user. You can see an example response here: https://tapstream.com/developer/ios/onboarding-links/#attribution-data
3. If there is data (you may want to output it for review) we grab hold of the custom_parameters  in the hits array. In this case, I’m only interested in value of the name  parameter. You can pass as many custom params to Tapstream as you wish.
4. If the name value is not nil, we present the OnboardingViewController  and assign the name value to the nameField.text property that we setup on the OnboardingLinkViewController .

That’s everything. Now we can get to testing. First build and run your project to ensure it compiles. At this point you should just see the Apple homepage again.

Now completely delete the app from your simulator. This is important. It has to be completely removed.

Next, open up your settings on the simulator and find the Safari settings. Clear all history and website data.

Open up Safari on the simulator and open a new PRIVATE browsing window. In the address bar, type the address for one of your Tapstream campaign links. This won’t work with an example link, so you’ll need to use a real link from your own Tapstream account. Using the one in the screenshot below won’t work for you. Add the parameter ?name=YOUR_NAME  and press enter.

Exit Safari and run your app. You should see the Apple homepage load, and after the three second delay we set, you should see the OnboardingLinkViewController  modally appear with the name ‘Michael’ set at the top.

Here is a complete video of the test. You can see the OnboardingLinkViewController  load after the three second delay we set. At the end, I run the app a second time to show it loading normally on subsequent launches.

As you can see, we used a Tapstream link to pass context through to the application. So now you can invite all your VIP’s to your amazing browser by simply appending their names to the end of the invite link in your email, advertisement, or basically anywhere you can place a link.

The possibilities here are nearly endless. If you’re an ecommerce app, you can pass shopping cart data to an app. Imagine a shopper on your mobile website about to checkout. You show them an offer that says, “Complete this transaction in our app and get free shipping”. The user downloads the app and when they open it for the first time, Tapstream’s deferred deep links have carried the users auth info and shopping cart over to the app so they can seamlessly complete the transaction.

The app stores have historically been a place where marketing data goes to die. Not anymore. Deferred deep links give you the ability to carry intent and context from web-to-app or app-to-app for all new users.

A few notes on testing. For deferred deep links to work, we must be able to attribute the user to a campaign link. Meaning, we have to generate a conversion. In real world usage this isn’t an issue but in testing you’re likely going to use the same links and devices over and over again. For this reason, it’s important to have clean sessions for each test.

Between each test of a deferred deep link you must:

  • completely remove the app from the device or simulator
    completely delete all cookies from your browser. Clearing the cache isn’t sufficient.
    It’s highly recommended to use a private browsing window while testing.

For more info, please see our docs on simulating conversions: https://tapstream.com/developer/simulating-conversions/

Again, if you have a paid Tapstream account and you just want to try the completed sample project, you can grab the source here: https://github.com/DevMoz/deferred-deep-links