72

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).

Kiran Panesar
  • 3,094
  • 2
  • 22
  • 28
  • Tracking an install from an ad on the device is different because they can correlate the IDFA. I don't believe that what you want to do is possible – Paulw11 Sep 15 '14 at 20:55
  • We're looking for ways to do this too. Have you seen this blog post from TapStream "How We built Deferred Deep Links" http://blog.tapstream.com/post/74394304157/how-we-built-deferred-deep-links – Ender2050 Oct 20 '14 at 13:08
  • @Ender2050 Yup, I mention Tapstream in the original post. I saw their blog post but it appears to just be an ad to use their services. I was mainly interested in how I could implement such a feature myself rather than relying on a third party. – Kiran Panesar Oct 27 '14 at 22:20
  • Kiran, thanks. I hope we're able to find some better options for this. – Ender2050 Oct 28 '14 at 00:29

4 Answers4

80

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.

okcoker
  • 1,329
  • 9
  • 16
ethangui
  • 1,285
  • 11
  • 15
  • 9
    Ethan, it sounds like you're describing what we do at Branch Metrics :) – st.derrick Apr 24 '15 at 21:47
  • 1
    thanks! exactly what I needed to understand this. What is the chance of conflict? Like what happens if 2 exact iphones click on a link from the same wifi connection (like conference). Is there information that is more unique to the device? – Nick Ginanto Jul 15 '15 at 14:09
  • Ethan, why did you choose branch.io over adjust (besides the free and support)? – Dat Nguyen Oct 30 '15 at 23:00
  • 5
    Since apple and android are constantly going out of their way to kill deferred deep linking methods that can uniquely ID a user/device, then why not just allow the app stores to accept an inbound parameter - then pass that parameter to the app upon launch. So frustraing. – rolinger Aug 08 '21 at 19:09
12

We've successfully used the clipboard (NSPasteboard) to achieve this: the web page that processes the redirect to the app store does a paste to the mobile device's clipboard before letting the user download the app. Once the app is installed, it uses NSPasteboard on first launch to check for an appropriately coded string. This string can contain the text of interest or, more securely, a token used to fetch interesting data from the backend. In Objective C:

UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
NSString *pasteboardString = pasteboard.string;

The clipboard can be cleared once the app is done with it, to avoid repeating the same action.

Anthony Scott
  • 1,311
  • 12
  • 9
  • 1
    According to this post https://stackoverflow.com/questions/34045777/copy-to-clipboard-using-javascript-in-ios they have disabled programmatic pasting by javascript to the clipboard on iOS, so this would no longer work. – Doug Voss Oct 24 '17 at 03:36
  • 1
    @DougVoss Programmatic pasting works in iOS 12 as long as you use the correct method (see top linked question) and do it in a click handler. This method worked great for us to maintain context when users first install the app by clicking a button on our mobile web landing page – Jeff Camera Feb 13 '19 at 16:44
  • Can confirm, I have tested this on iOS 13, with a simple react website and iOS app. It works perfectly. – Johno2110 Nov 19 '19 at 00:37
  • wait, so this approach works? Apple won't reject your app or anything? Do I still need to disclose that we do attribution? (without using IDFA) – Nagendra Rao Mar 05 '21 at 10:28
  • iOS 14 has made thi harder, Safari doesn't let you copy stuff without actual user triggered "click" or "touch" event, even if you get the data written to phone's clipboard, when you try to read it (once user installs the app), iOS 14 will show user that you read their clipboard. This is not a good experience. Probably best to go with solution like branch.io, like stated in the other answer. – Nagendra Rao Mar 07 '21 at 13:40
10

There is a good solution here: http://blogs.innovationm.com/deferred-deep-linking-in-ios-with-universal-link/

Basic workflow:

  • User selects domain link on web.
  • Link sets referral ID to cookie.
  • User redirected to app store.
  • On app launch, load referral page in SFSafariViewController.
  • Referral page checks for cookie and if it exists calls a deeplink into the app with the referral ID.
PPierson
  • 410
  • 3
  • 18
  • Yes - except there is an explicit section in the SFSafariViewController that it may only be used to visibly display information to users, so using it in this way is directly violating that rule basically. Problematic. – n13 Jul 09 '18 at 07:16
  • 19
    Looks like starting from iOS 11 cookies from Safari app and `SFSafariViewController` aren't shared, so it won't work anymore – Alexander Vasenin Aug 09 '18 at 22:36
  • Is there a way to grab the cookie from `WKWebView` or `SFSafariViewController` today in 2019? – William Grand Mar 14 '19 at 20:18
  • 1
    Apple killed this approach. It doesn't work anymore. – Nagendra Rao Mar 07 '21 at 13:41
-8

My answer from HERE

Apple no longer supports Deep Links. It is now called Universal Links and works a bit differently.

Source

Now that Apple no longer supports URI schemes for deep linking, developers must implement Universal Links in order to deep link properly on iOS. If you are already using URI schemes, check out our blog on transitioning to Universal Links.

From: HERE

And HERE is another article on Universal Links and what they are.

Community
  • 1
  • 1
devtech
  • 325
  • 1
  • 12
  • 1
    The question is about deferred deep-linking, which Universal Links does not solve. – PPierson May 15 '17 at 21:01
  • OP clearly states the need to persist parameters between the moment the user taps a link (facebook campaign for example) and after the app has been installed so that the user can be taken to certain part of the app for instance. – Lee Andrew Jun 12 '17 at 16:12