Deferred Deep Linking in iOS

Kiran Panesar picture Kiran Panesar · Sep 15, 2014 · Viewed 28.1k times · Source

We're trying to implement deferred deep linking in one of our iOS applications to encourage users to invite their friends to use the app, and reward users based on how many installs occur from their referral link. Basically similar to TapStream's product.

Consider this example:

So, UserA shares their link, “ourappURL.com/refer?id=userA”, on any network they want. UserB clicks that link, which will take them to Safari and then bounce them to the App Store page where UserB downloads the app.

When UserB opens the app, the app checks which referral ID they came in on (if any). In this example, the referral ID would be “userA” as that’s the ID that was in the referral link. The app then sends this to our servers and we award UserA with a referral credit.

I'm trying to break this issue down into its core parts. I believe the first part is getting the web page for the user's referral link to save the referral ID to the device somewhere that the app can access it. But I'm not sure this is possible because of the sandboxed nature of iOS.

I know this is fundamentally possible because many ad providers offer the ability to track installations from an ad campaign (see Mobile App Tracking for example).

Answer

ethangui picture ethangui · Apr 2, 2015

We have also attempted to do this ourselves and I will try to break down the different steps here.

Going back to your example, you are correct about "remembering" the device identification, and all relevant data "id=userA". You are also correct about "sandboxed nature of iOS" which I presume it means a web page is not allowed to store information outside of the browser app (Safari) and apps (your app) are not able to access information stored by other apps (Safari).

Our solution to this is to store this device to data key-value pair in an environment that is both accessible by the browser as well as by your app, i.e. your backend server.

The next challenge, which remains to be the biggest challenge, is how to uniquely identify this device from the information collectable from the browser? Javascripts in browsers, unlike native apps, don't have access to IDFAs which could be used to uniquely identify a iOS device. To overcome this, one can imagine to use a combination of common information that is available both to the browser app as well to your native app, i.e. OS type, public IP, screen size, etc. etc. Please note, a composite key from these data fields does not guarantee uniqueness (imagine two iPhone 6 visiting this web page via the same router). Therefore, your backend server (assuming you are using it to store this key-value pair), will want to have a strategy on how to handle collisions on keys i.e. the second key deletes the first key, or you allow collision to exist by having a queue of values for a single key. This really depends on how you actual plan to use this technology.

The last step is to form this composite key on your app using the exact same fields you used earlier in the browser to perform a "lookup" on your backend server to retrieve the value previously stored.

Here is a summary of the steps:

  1. User 1 invites User 2 by sending the following link to 2: example.com?inviter=1
  2. User 2 visit Web Page P
  3. P constructs and sends the following key-value pair to your server S iOS|55.55.55.55|750×1334 -> inviter_id=1
  4. User 2 goes to the app store and downloads your App A
  5. User 2 first launches A, A contacts S with the same key (assuming the IP hasn't changed).
  6. S finds the value inviter_id=1 by using this key passed in and, let's say, reward User 1 five points for inviting 2.

Hope this help!

Edit 04/24:

Since Derrick mentioned it in the comments, I figure I would take this chance to finish our story here.

Going back to the beginning of my answer where I mentioned we've attempted to do this ourselves. We had a working prototype based on our current system architecture (which is not in anyway optimized, or meant to be optimized, for storing and analyzing deep link data like this), we ultimately decided not to allocate any additional engineering resource into this project.

Due to the heuristic nature of this matching process, we found this project needing debugging, tuning and optimizing constantly for a diminishing ROI. More importantly, we have found other companies which are more specialized and do a much better job than ourselves.

It has been probably 6 months since we stopped using our internal system and we haven't regretted making such decision.

During this processes, we've worked with a number of vendors, Appsflyer, Adjust, TapStream and we have ultimately ended up with Branch Metrics https://branch.io.

Whether you should DIY or work with another company again depends on your specific objective. We finally decided to stay with Branch, not only because the other vendors charged anywhere from $500 to thousands of dollars per month while Branch is completely free, but also the level of the support they have provided is simply unparalleled.