APP Wakeup and Scene Restoration

In App launch promotion, waking up users is a common operation strategy. To get users active again and convert their behavior, the path of users must be restored from the scene to find the mystery of user growth from the root.

In this era of advertising, I believe most users have encountered a similar scenario when using an app: when using an information app, they browsed to a Taobao product advertisement, and when you clicked on the content of the advertisement, it automatically opened the Taobao app already installed on your mobile phone and positioned to the details page of the product.

  • As a user, you must be thinking: “This is so convenient, I don’t even need to open Taobao to search for products”.
  • As an advertiser, you’re thinking: “I’ve got another user, maybe I’ll even get a conversion”.

So, how does the information app wake up the Taobao App, and how does the Taobao App jump to the ad page that the user is browsing?

Waking up & scene restoration, as a common means of pulling live growth in operations, is conducive to enhancing the activity of old users in the App, and the scenario-based waking up is more likely to stimulate users’ willingness to convert.

It is applicable to several marketing scenarios as follows.

  • Browser -> Wake up APP: User A opened the M site or official website of an APP through the browser on his mobile phone, then guide the user to open the APP or download the APP.
  • WeChat, QQ, etc. -> Wake up APP: User shared a link to WeChat or QQ through an APP, and after user B clicked the link, user B was guided to open the APP or download the APP.
  • SMS, email, QR code, etc. -> Wake up APP: User A opened a promotional SMS, email or scanned QR code of an APP, leading the user to open the APP or download the APP.
  • Other APP -> Wake up APP: User A shared a link to User B through a third party APP, and after User B clicked on the link, User B was guided to open the specified APP or download the specified APP.

sobyte

Common ways to wake up an app

URL Scheme

URI Schema is the most primitive of these methods, it only requires a scheme to be registered during native app development, then when the user clicks on such a link, the app will automatically wake up, and with the help of the URL Router mechanism, it can also jump to a specific page. This is the most widely used and simplest method, but it requires the app to support URL Scheme.

iOS URL Scheme

Sandboxing for iOS

iOS has chosen to sandbox to protect user privacy and security, but sandboxing also prevents reasonable information sharing between apps, so URL Schemes is the solution. Generally speaking, the smart devices we use have a lot of our personal information on them. For example: contact details, bank/credit card information, account passwords for Alipay/Paypal/major stores, photos and even travel and location information.

If every app on your device, whether official or installed from any store, has access to this information at will, you could receive harassing messages and emails, or even serious consequences. How to keep this information out of the hands of other apps, or how to keep it out of the hands of the device owner, is a core security concern for all smart devices and operating systems.

In the case of iOS, Apple uses a mechanism called ‘sandboxing’ to address this issue: apps can only access resources that they have declared they can access. All apps submitted to the App Store must adhere to this mechanism.

Sandboxing is a good solution in terms of security, but it is an overkill. Just because we don’t want to disclose sensitive personal information doesn’t mean that we don’t want to share all that information with other apps. For example, if we want to put multiple events into our calendar at once (yes, just once), with information such as date and time and duration, we can’t do this if the information is not communicated between apps. Something like adding multiple calendar events at once is a lot of unnecessary repetitive steps we encounter when using our smart devices. Most people are unaware of these repetitive steps, like when they have a batch of files on their computer that need to be renamed in bulk and they mechanically repeat the renaming process. But when we get to grips with the patterns in which these devices operate, or have some tools at our disposal, we can save all these repetitive steps. On iOS, one tool we can use is URL Schemes.

What URL Schemes are

It should be much easier to understand URL Schemes on iOS by comparing web links.

URL Schemes has two words.

  • URL, which we all know well - http://www.apple.com is a URL, which we also call a link or URL.
  • Schemes, which refers to a location in a URL - the initial location, i.e. the character before ://. For example, the Schemes for the URL http://www.apple.com is http.

Based on our use of URL Schemes above, we can easily see that on iOS, which is primarily a native application, we can use a special URL to locate an application or even a specific function within an application, just like we can locate a web page. What locates the app is the Schemes part of the app’s URL, which is the opening part. For example, SMS is sms:

You can understand the URL of an iOS app in exactly the same way as you understand the URL of a web page - that is, its URL.

Web (Apple) iOS App (WeChat)
Web Home/Open App http://www.apple.com weixin://
subpages/specific features http://www.apple.com/mac/ weixin://dl/moments

Here, http://www.apple.com and weixin:// both declare whose territory this is. Then add /mac to http://www.apple.com to jump to a web page (Mac page) belonging to http://www.apple.com; similarly, add dl/moments to weixin:// to go to a specific WeChat function - the -moments.

However, there are several other important differences between the two.

  • All web pages must have a URL, whether it is the home page or a sub-page. In fact, the status quo is that most apps only have URL Schemes for opening apps, and some apps don’t even have URL Schemes for opening apps. almost no app has a URL for every function. Almost no apps have URLs for all functions. So, don’t say that so-and-so sucks and doesn’t support domestic apps. Whether an app supports URL Schemes depends on whether the author of that app has added URL Schemes-related code to his work.
  • A URL only corresponds to one web page, but not every URL Schemes corresponds to one app. This is because Apple does not have a mandatory requirement for URL Schemes not to be duplicated, so there have been incidents where apps have used Paypal URL Schemes to block payment accounts and passwords.
  • URL Schemes on iOS are very difficult to guess because there is no standardized URL Scheme, so it is not practical to guess the URL Schemes of iOS apps.

Basic URL Schemes

Basic URL Schemes are simple and limited in their capabilities, but they are the most common use case. By basic URL Schemes, we mean the Schemes part of a URL, such as the weixin: of WeChat mentioned above. The only function of this section is to open the corresponding application, without the ability to jump to any function.

The majority of apps that support URL Schemes generally have only one section, which is usually the name of the app, such as OmniFocus, whose basic URL Schemes is Omnifocus:. If the app’s main name is a Chinese name, its URL Schemes might be the pinyin for the app’s name, such as moke, whose basic URL Schemes is moke:. But the third of three important differences between web URLs and iOS app URLs is that URL Schemes on iOS are not standardised, and an app’s URL can be anything from

  • Coursera’s URL is: coursera-mobile:
  • The URL for the game Duet is: x-kumo-duet:
  • The URL for the game Monument is: fb690517270143345:
  • The URL for Feedly is: fb129765800430121:
  • The URL for Fanzine News is: wx95962d02b9c3e2f7:

They don’t currently have uniform rules, so there’s not much point in guessing an app; you can try, but don’t count too much on that approach. The following section will mention how to find the basic URL Schemes for an application, as long as that application supports URL Schemes. Basic URL Schemes are simple and limited in their ability, but the context of use is the most common.

Complex URL Schemes

Mastering complex URL schemes gives you the initial ability to create automated processes that are adapted to your context. complex URL schemes for iOS apps are like links to sub-pages of a website, extending from the home page URL.

Specifically, there are two types of complex URL schemes: one that opens a feature of an app directly, and another that opens a feature and fills in pre-defined characters directly. This makes it a much more useful URL Schemes, as it not only takes you directly to the interface of a feature you need, but also fills in the content you need directly for you, and after the jump, all you need to do is click Done.

With URL schemes like this, apps can collaborate with each other. For example, when we see an article on Mr. Reader with a great piece of software, we can use OmniFocus URL Schemes to save the article name to the task name section and the link to the notes section. Until the advent of iOS 8’s Share Sheet, this was the only way to transfer information between apps.

A special use case for complex URL Schemes is Jumpback, which is used a lot by dictionary apps, such as Eurodictionary. The traditional URL Schemes for looking up words using Eurodictionary are

1
eudic://dict/想查的单词

To this, add the phrase Jumpback.

1
eudic://dict/想查的单词?jumpback=指定URL

You will be able to press the back button in the top or bottom left corner to return to the app you want to go back to after looking up a word.

Not every app has its own complex URL Schemes, but generally speaking, apps with systematically standardised complex URL Schemes are the best of their kind.

x-callback-URL

Once you have jumped from one app’s interface to another, you will see the words back to the previous app in the top left corner, and a tap will return you to the previous app. This is something we will no doubt want to do when we build our own automation, and while the aforementioned Jumpback is one option, there is a more powerful alternative - x-callback-URL - which has something that the ‘back to previous app’ feature on iOS 9 cannot replace. What But there’s no denying that x-callback-URL is less contextual and more difficult to use.

The URL Schemes we talked about earlier all have one purpose, and whatever the result, the jump will stay in the redirected application’s interface once it is complete. However, when using URL Schemes, the result of the run may or may not work, and sometimes we will manually disable it.

If we also want the application to react to different results, we need to use x-callback-URL, for example, when the last URL Schemes run succeeds, do I go back to the application before the jump? Or do I want to take another action (take another URL Scheme and open a function in another application)? Whether you want to jump back to the previous application or open another action, whenever you want to do the next thing with a new URL Scheme after running one, you rely on x-callback-URL, which has the following fixed syntax.

  • appending &x-success to a URL Schemes to indicate what to do next after the previous URL succeeded.
  • A URL Schemes followed by &x-error, indicating what to do next after the previous URL failed.
  • a URL Schemes followed by &x-cancel, indicating what to do next after cancelling the result of the previous URL.
  • There is also an &x-source which we will talk about when we come across it.

Encoding of URLs

The characters in a URL can be divided into two categories, some of which can be displayed normally in a link, such as letters, numbers and some symbols such as /. Other than that, all characters cannot be displayed normally and need to be encoded to appear as part of the URL. For example, spaces must be represented as %20 in the URL, and there are many tools available on the web to encode and decode URLs, so that they can be decoded to make them look good to us. These tools can, of course, in turn convert our common characters into characters that can be used in URLs.

So theoretically, all characters that are not supported by URLs have to be encoded.

Custom URL Scheme for jumping

If we want someone to open our app (named SchemeDemo), we need to register a custom URL Scheme by going to info.plist -> URL Types -> item0 -> URL Schemes -> Your TestScheme to set it up, the steps are as follows.

  1. Click on the info.plist file in your project, when the file is displayed in the following window, mouse over the Information Property List at the top of the list, select +, then scroll down the pop-up list and select URL types, type NSArray.

    sobyte

  2. click on the URL types left cut header to open the list, you can see Item 0, a dictionary entity. Expand Item 0 and you will see URL Identifier, a string object. This string is the name of your custom URL scheme. It is recommended that the name is unique by reversing the domain name, e.g. com.yourCompany.yourApp.

    sobyte

  3. Click on Item 0 to add a new row, select URL Schemes from the drop down list and hit the Enter key to complete the insertion. Note that URL Schemes is an array that allows applications to define multiple URL schemes.

    sobyte

  4. Expand the URL Schemes data and click on Item 0. Here you will define the name of your custom URL scheme. Just the name, do not append ://, for example, if you type iOSDevApp, your custom url will be iOSDevApp://.

    image

At this point, the entire definition is as follows.

sobyte

Android URL Scheme

The custom URL Scheme in Android is an in-page jumping protocol, also known as a URLRouter, that routes an Activity through a web page in a similar way to opening a web page, rather than directly through an explicit Intent. The benefits of this implicit intent method jumping are as follows.

  • Reduced coupling: no need to know exactly which interface to jump to, just send the Intent according to the agreed URL routing protocol, as required.
  • Safer: no Intent jumps are shown, as long as the Intent that matches the protocol is matched by the corresponding Activity, avoiding jumps to pages that shouldn’t be there.
  • More flexible: there is a wider range of application scenarios, and URL Scheme can be used in a variety of scenarios

URL Scheme protocol format.

As mentioned above, the URL Scheme is a similar way to open a web page to open an Activity through a route, and the protocol format is similar to the URL we enter to open a web page.

A complete URL Scheme protocol consists of scheme, host, port, path and query, and is structured as follows.

1
<scheme>://<host>:<port>/<path>?<query>

The common protocols in Android include content protocol, http protocol, file protocol, etc. Custom protocols can use custom strings, which are mostly used when we launch third-party applications.

The following is the URI of a custom protocol: xl://goods:8888/goodsDetail?goodsId=10011002

With the above path Scheme, Host, port, path, query all contain:

  • xl, which is Scheme and represents the Scheme protocol name
  • goods, which is the Host, which represents the address domain that the Scheme acts on
  • 8888, which is the port, representing the port number of the path
  • goodsDetail, which is the path, representing the page specified by the Scheme
  • goodsId, which is the query, represents the parameter passed

How to use URL Scheme

In short, the use of URL Scheme is to first configure the activity in the manifest that can accept the Scheme method to start; when it needs to be called, add the Scheme protocol’s URi to the Intent in the form of Data, and call the activity implicitly.

  1. Add <intent-filter> to the <activity> tag in AndroidManifest.xml to set Scheme
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<activity android:name=".MainActivity">
    <intent-filter> <!--正常启动-->
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
    <intent-filter> <!--URL Scheme启动-->
        <!--必有项-->
        <action android:name="android.intent.action.VIEW"/>
        <!--如果希望该应用可以通过浏览器的连接启动,则添加该项-->
        <category android:name="android.intent.category.BROWSABLE"/>
        <!--表示该页面可以被隐式调用,必须加上该项-->
        <category android:name="android.intent.category.DEFAULT"/>
        <!--协议部分-->
        <data android:scheme="urlscheme"
            android:host="auth_activity">
    </intent-filter>
    <intent-filter>
        <action   android:name="emms.intent.action.check_authorization"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="emms.intent.category.authorization"/>
    </intent-filter>
</activity>

As you can see in the above settings, MainActivity contains multiple <intent-filter> settings, the first being the normal launch, i.e. launching in the application list; the second being the launch via URL Scheme, which is itself a type of implicit Intent call, the difference being the addition of the <data> attribute, which defines its acceptance The URL Scheme protocol format is urlschemel://auth_activity

It is important to note that the attributes that make up the URI in the URL Scheme protocol format are optional in the <data > tag, but there are dependencies as follows.

  • if no scheme is specified, then the host parameter is ignored
  • If host is not specified, then the port parameter is ignored
  • If neither scheme nor host is specified, the path parameter is ignored

When we compare the Uri parameter in the intent object with the URI format specified by the <data> tag in the intent-filter, we only compare the part specified by the <data> tag in the intent-filter, e.g.

  • If only the scheme is specified in the intent-filter, then all URIs with that sheme will match that intent-filter.
  • If only scheme and authority (authority includes both host and port) are specified in the intent-filter and no path is specified, then all URIs with the same scheme and authority will match that intent-filter regardless of what path is.
  • If both scheme, authority and path are specified in the intent-filter, then only URIs with the same scheme, authority and path will match the intent-filter.

Note that the <data> tag of an intent-filter can use the wildcard * character inside when specifying the value of path, to provide a partial match.

  1. Launching an Activity using a URL
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Uri data = Uri.parse("urlschemel://auth_activity");
 Intent intent = new Intent(Intent.ACTION_VIEW,data);
 //保证新启动的APP有单独的堆栈,如果希望新启动的APP和原有APP使用同一个堆栈则去掉该项
 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 try {
   startActivityForResult(intent, RESULT_OK);
 } catch (Exception e) {
   e.printStackTrace();
   Toast.makeText(MainActivity.this, "没有匹配的APP,请下载安装",Toast.LENGTH_SHORT).show();
 }

It is of course possible to call from the web page.

1
<a href="urlschemel://auth_activity">打开新的应用</a>

Alternatively, call in JS.

1
window.location = "urlschemel://auth_activity";
  1. How to determine if a URL Scheme is valid
1
2
3
4
5
boolean checkUrlScheme(Intent intent){
    PackageManager packageManager = getPackageManager();
    List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
    return !activities.isEmpty();
}

Hide sub-apps in Home Launcher

Sometimes it is necessary to hide some secondary, more independent APPs in the Home Launcher and only allow some specific APPs to call them. In this case, we can use the URL Scheme protocol to do this, setting the <activity > tag in AndroidManifest.xml as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<activity android:name=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <!--表示该页面可以被隐式调用,必须加上该项-->
        <category android:name="android.intent.category.DEFAULT"/>
        <!--协议部分-->
        <data android:scheme="urlscheme"
            android:host="auth_activity">
    </intent-filter>
</activity>

Because the Home Launcher lists application icons that require an Activity to also meet.

1
2
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>

The above configuration has redundant category and data restrictions present, so it does not match and will not appear in Home Launcher, but can be launched using URL Scheme.

1
2
3
Uri data = Uri.parse("urlschemel://auth_activity");
Intent intent = new Intent(Intent.ACTION_MAIN,data);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

This allows a group of APPs to be set up with a unified entry point, and then different sub-APPs can be invoked according to actual needs, i.e. the so-called APP business componentization.

Disadvantages of URL Scheme

Hint box

We can only jump through links with fixed protocol format, and when opening an H5 page, a prompt box will appear: “Do you want to open XXX”. The user confirms it before jumping to the App, adding to the user process.

Exceptions caused by not installing the App

The error handling situation is difficult to handle uniformly depending on the platform, some APPs will directly jump to the error page (e.g. Android Chrome/41, old Lofter in iOS); some stay on the original page but pop up a prompt “cannot open the page” (e.g. iOS7); iOS8 and the latest Android Chrome/43 currently stay directly on the current page without popping up an error prompt.

Scenario support

In iOS, Tencent’s WeChat and QQ are explicitly forbidden to be used. iOS9 and later Safari no longer support triggering scheme jumps through js, iframes, etc., and a confirmation mechanism has been added, making it basically impossible to automatically wake up the APP through the js timeout mechanism; Android platform varies greatly from app vendor to app vendor, for example, Chrome is the same as Safari since 25 and later.

Naming conflicts or hijacking

Apple has adopted the first-come, first-served principle in subsequent versions of iOS (iOS 11), so that if the same URL scheme is used, only the app that was installed first will be launched. However, an attacker can still exploit this vulnerability in other ways.

Opening method is banned

WeChat and QQ have banned URL Scheme from opening apps, but they each maintain a whitelist, so if Scheme is not on that whitelist, then the app cannot be opened from within their app (if it is blocked then the user can only open the app from within the browser in the top right corner)

Universal Link is one of the new features of iOS9 introduced by Apple at WWDC. This feature is similar to deep linking and makes it easy to launch your client app (with an app installed on your phone) directly by opening an Https link. This new feature provides an excellent user experience when seamlessly linking web-apps compared to the URL Scheme used previously.

When your app supports Universal Link, when a user clicks on a link they can jump to your website and get a seamless redirect to the corresponding app, without the need to go through Safari. If your app does not support it, the link will open in Safari.

Using Universal Link allows users to pull up the corresponding APP in the Safari browser or in the webview of another APP, as well as using the corresponding function within the APP to drive users to the APP. What does this look like? For example, you have a user browsing your company’s website in safari, and you have your app installed on your phone; Universal Link enables the user to open your app directly when they open a detail page and reach the corresponding content page in the app to perform the action they want (e.g. view a news item, view the details of a product, etc.). The Universal Link allows the user to open a detail page of your app and go directly to the corresponding content page in the app to perform the action they want (e.g. view a news item, view a product detail, etc.). For example, if you go to the Taobao website in Safari and click on the app, the Universal Link is used to pull up the Taobao app.

Advantages of Universal Link:

  • Custom URL scheme is a custom protocol and therefore cannot be opened directly without the app being installed. Universal Links is itself a standard web link that can point to a web page or content page within the app (e.g. https://example.com) and is therefore very compatible with other situations. This means that when the app is installed, the app will be launched immediately without loading any web pages; when the app is not installed, it will redirect the user from the current browser to the App Store by default to download and install the app.
  • Universal links looks up which app needs to be opened from the server, so there is no name grabbing or conflict as in the Custom URL scheme.
  • Universal links supports jumping to the target app from a UIWebView in another app
  • Security, when using a universal link to open, only you can open your app by creating and uploading a file that allows this page to go to your app via this URL.
  • Privacy, providing a universal link to other apps for inter-app communication, however the other app cannot use this method to detect if your app is installed.

Features of Universal link.

  • Uniqueness: Unlike a custom URL scheme, it uses the standard HTTPS protocol to link to your web site, so it is generally not claimed by other APPs. In addition, the URL scheme cannot be opened directly without an app installed because it is a custom protocol (and a pop-up window will appear in Safari that will not open), whereas Universal Link is itself an HTTPS link and therefore has better compatibility.
  • Security: when your APP is installed on the user’s phone, the system will go to the website you have configured and download the instructions file you uploaded (this instruction file declares which APPs can be opened by the current HTTPS link). Since only you can upload files to the root of your website, the association between your website and your APP is secure.
  • Variable: Universal Link (Universal Link) works even when your APP is not installed on the user’s phone. If you wish, a user clicking on a link without your app installed will display the content of your website in safari.
  • Simple: an HTTPS link that works for both the website and the APP.
  • Private: other APPs can communicate with your APP without needing to know whether your APP is installed or not.

Universal link configuration and operation

  1. Configure App IDs to support Associated Domains

Go to https://developer.apple.com/ and locate the App ID in the Apple Developer Center, and in the Application Services list, there is an entry for Associated Domains. Make it Enabled and you’re good to go.

  1. Configure the iOS App project

Xcode version 11.0: Project configuration: targets->Signing&Capabilites->Capability->Associated Domains, fill in the Domains you want to support, you must also prefix it with applinks.

Xcode 11.0 and below: Project Configuration: targets->Capabilites->Associated Domains, enter the domain name you wish to support in the Domains section, which must be prefixed with applinks.

  1. Configure and upload apple-app-association

Exactly which URLs will be recognised as Universal Links depends on this apple-app-association file Apple Document UniversalLinks.html

  • Your domain must support Https
  • Put this file apple-app-association under the root of your domain or .well known directory without any suffixes.
  • The file is json and can be saved as text
  • json according to the official website

apple-app-site-association template.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{
    "applinks": {
        "apps": [],
        "details": [
            {
                "appID": "9JA89QQLNQ.com.apple.wwdc",
                "paths": [ "/wwdc/news/", "/videos/wwdc/2015/*"]
            },
            {
                "appID": "ABCD1234.com.apple.wwdc",
                "paths": [ "*" ]
            }
        ]
    }
}

Description.

  • appID: the composition is yourapp’s bundle identifier. e.g. 9JA89QQLNQ above is teamId. login to developer centre, you can find the team ID in Account -> Membership.
  • paths: Set the list of paths supported by your app, only links from these specified paths will be processed by the app. The asterisk means that all links under the domain are recognised.

Upload the specified file: Upload the file to the root directory or .well known directory of your domain, so that Apple can get the file you uploaded. Once you have uploaded the file, visit it yourself to see if it is available. When you type the link into your browser, it should download the apple-app-site-association file directly.

Verify Universal link is active.

You can use the memo app that comes with iOS, enter the link, long press the link and if the pop-up menu says “Open in ‘xxx’”, then the configuration is active. Alternatively, open the URL you want to test in Safari and scroll down to the top of the page that appears and you will see the “Open in ‘xxx’ app” menu.

sobyte

When a link is clicked, it will take you directly to our app, but our aim is to be able to get the link the user came from and show the user the appropriate content based on the link.

The official link to implement the proxy method in AppDelegate: Handling Universal Links

Objective-C:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler {
    if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb])
    {
        NSURL *url = userActivity.webpageURL;
        if (url是我们希望处理的)
        {
            //进行我们的处理
        }
        else
        {
            [[UIApplication sharedApplication] openURL:url];
        }
    }
     
    return YES;
}

Swift:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
func application(_ application: UIApplication,
                 continue userActivity: NSUserActivity,
                 restorationHandler: @escaping ([Any]?) -> Void) -> Bool
{
    guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
        let incomingURL = userActivity.webpageURL,
        let components = NSURLComponents(url: incomingURL, resolvingAgainstBaseURL: true),
        let path = components.path,
        let params = components.queryItems else {
            return false
    }
    
    print("path = \(path)")
    
    if let albumName = params.first(where: { $0.name == "albumname" } )?.value,
        let photoIndex = params.first(where: { $0.name == "index" })?.value {
        
        print("album = \(albumName)")
        print("photoIndex = \(photoIndex)")
        return true
        
    } else {
        print("Either album name or photo index missing")
        return false
    }
}

Universal link cross domain issues

Universal Link has cross-domain problem, Universal Link must require cross-domain, if not, it will not jump (iOS 9.2 after the change) require cross-domain capability can be, if the current web page domain is A, the current web page launch jump domain is B, must require B and A is a different domain to trigger Universal Link, if B and A is the same domain, it will only continue to jump in the current WebView. If B and A are the same domain, it will only continue to jump inside the current WebView, even if your Universal Link is working fine and will not open the app at all. 2. Universal Link request apple-app- site-association timing

Universal Link updates

The apple-app-association is updated at two times.

  • The first Launch after each App installation will pull apple-app-association
  • The first Launch of the Appstore after each App version update will also update apple-app-association

So repeatedly re-killing the app and reopening it is completely useless. Deleting the app and reinstalling it does work, but it is unlikely that users will be allowed to do so. That said, once you accidentally apple-app-association by accident and want to redeem and make that part of the user indifferent, the App will just release another version.

Universal Link user behaviour

Universal Link triggered after opening the App, at this time the App’s status bar will have a text prompt from XXApp in the upper right corner, you can tap the status bar text to quickly return to the original AP

If the user taps back to WeChat, it will be remembered by Apple that the user does not need to jump out of the original app to open a new app, so the Universal Link for this app will be turned off and will never be valid again.

It is not impossible to turn it on by asking the user to re-open the Universal Link page in Safari and then something like the Apple smart bar will appear, which will open when tapped

H5-side Universal Link business deployment

The Universal Link jump on the H5 side, from a product manager’s point of view, needs to meet 2 requirements.

  • If an App is installed, the corresponding interface will be redirected
  • If no App is installed, jump to the App download interface

Example of Universal Link deployment on the H5 side.

1
2
3
4
router.use('/view', function (req, res, next) {
    var path = req.path;
    res.redirect('https://www.xxx.com/view' + path + '?xxx=xxx');
});

The whole effect is

  • Jump to https://www.xxx.com/view/*
    • App installed
      • Open App triggers handleUniversalLink
      • Goes to the /view/ branch and splices the reading page to route the jump
    • AppWebView is not installed
      • Jump in place https://www.xxx.com/view/*
      • Hit the server’s redirection logic
      • redirects to https://www.xxx.com/view/*
      • Open the corresponding H5 page

Chrome Intent

In many applications we need to launch the application directly from the browser, most of them use the first scheme way mentioned above, the problem is that if there is no application in the phone, the url will jump to an error screen.

Google has officially introduced a way to launch apps in chrome with Android Intents, by setting the src in the iframe to

  • intent:HOST/URI-path // Optional host
  • #Intent;
  • package=[string];
  • action=[string];
  • category=[string];
  • component=[string];
  • scheme=[string];
  • end;

The mainfest file defines the activity to be launched.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<activity
    android:name=".ui.activity.SplashActivity"
    android:exported="true"
    android:screenOrientation="portrait"
    android:theme="@style/NormalSplash">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data
            android:host="app.puxinwangxiao.com"
            android:scheme="pxwxstudent" />
    </intent-filter>
</activity>

Define an a tag as

1
<a href="intent://app.domain.com/#Intent;scheme=xyz;package=com.xxx.xxx;end">open Android App</a>

Click on the a tag in the browser to launch the corresponding activity of the application. If there is no corresponding application in the phone to prevent jumping to the wrong page, set the a tag to

1
<a href="intent://app.domain.com/#Intent;scheme= xyz;package=com.xxx.xxx;S.browser_fallback_url=https://www.domain.com;end">open Android App</a>

This way if there is no corresponding app, the link will jump to the url specified by ==S.browser_fallback_url===.

Note: Many third party browsers will block requests for chrome intent to launch applications.

Similar to Universal Links, Android App Link takes a similar mechanism: it uses a standard web page URL and binds the corresponding App. This mechanism is supported on Android >= 6.

Android App Links have the following benefits.

  • Security/specificity: since Android App Links use HTTP/HTTPS URLs to authenticate the connection to the developer’s server, other apps cannot use our links
  • Seamless user experience: When a user does not install our app, it will open a web page directly due to the use of HTTP/HTTPS URLs, where we can show the app description etc. instead of displaying a 404 or other error page
  • Support for Instant Apps: you can use App Links to open an uninstalled Instant App directly.
  • Support for Google Search or other browsers: users can open our specific page directly in Google Search/Google Assistant/Mobile Browser/Screen Search by clicking on a URL directly.

To add Android App Links to the app, you need to define an intent filter in the app that opens the app via the Http(s) address and verify that you actually own the app and the site. If the system successfully verifies that you own the site, then the system will route the intent corresponding to the URL directly to your app.

In order to verify your ownership of the app and website, the following two steps are necessary.

  • Ask the system in AndroidManifest to automatically perform ownership verification of App Links. This configuration tells the Android system to verify that your app belongs to the URL domain specified within the intent filter.
  • Place a Json file of digital asset links declaring the relationship between your URL and the app in the following link address: https://domain.name/.well-known/assetlinks.json

Activate App links in the app

Tell Android to verify the relationship between the app and the domain name. Since we have already registered the domain in the app, no more pop-up boxes will appear. Find the AndroidManifest.xml file and add android:autoVerify=“true” to intent- in the activity that handles deep link routing (step 3 will explain how to create such an activity). filter.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<activity
  android:name=".ParseDeepLinkActivity"
  android:alwaysRetainTaskState="true"
  android:launchMode="singleTask"
  android:noHistory="true"
  android:theme="@android:style/Theme.Translucent.NoTitleBar">
  
  <intent-filter android:autoVerify="true">
    <data android:scheme="http" android:host="yourdomain.com" />
    <data android:scheme="https" android:host="yourdomain.com" />
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
  </intent-filter>
</activity>

This configuration tells Android to validate a file which is located at https://yourdomain.com/.well-known/statements.json. If this file exists and also validates successfully, then when the user clicks on the link under that domain, they can go directly to the app and the pop-up box can be avoided. Otherwise the app is not made the default option and the pop-up box is presented to the user.

Upload web-app association file (statements.json)

For security reasons, this file must be obtained via a GET request over SSL.

1
2
3
4
5
6
7
8
[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.mycompany.myapp",
    "sha256_cert_fingerprints": ["6C:EC:C5:0E:34:AE....EB:0C:9B"]
  }
}]

The package name of the app can be found in the AndroidManifest.xml file. ava keytool should also be run in the terminal to generate a sha256 fingerprint

1
keytool -list -v -keystore /path/to/app/release-key.keystore

You need to add the path to the app that holds the app release keys to the keystore. This path depends on the project settings and is therefore different for different apps. More information on how to find the keystore can be found in the Google documentation.

Finally, upload this file to the server at /.well known/statements.json. To avoid having to access the network for every future app link request, Android will only check this file when the app is installed. If you can see this file when you request https://yourdomain.com/.well-known/statements.json (replace it with your own domain name haha) then you can move on to the next step.

Note: Currently you can get this file via http, but in the final version of M you can only authenticate via HTTPS. Make sure your web site supports HTTPS requests.

Handle applink in app

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class ParseDeepLinkActivity extends Activity {
  public static final String PRODUCTS_DEEP_LINK = "/products";
  public static final String XMAS_DEEP_LINK = "/campaigns/xmas";
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
 
    // Extrapolates the deeplink data
    Intent intent = getIntent();
    Uri deeplink = intent.getData();
 
    // Parse the deeplink and take the adequate action 
    if (deeplink != null) {
      parseDeepLink(deeplink);
    }
  }
  
  private void parseDeepLink(Uri deeplink) {
    // The path of the deep link, e.g. '/products/123?coupon=save90'
    String path = deeplink.getPath();
 
    if (path.startsWith(PRODUCTS_DEEP_LINK)) {
      // Handles a product deep link
      Intent intent = new Intent(this, ProductActivity.class);
      intent.putExtra("id", deeplink.getLastPathSegment()); // 123
      intent.putExtra("coupon", deeplink.getQueryParameter("coupon")); // save90
      startActivity(intent);
    } else if (XMAS_DEEP_LINK.equals(path)) {
      // Handles a special xmas deep link
      startActivity(new Intent(this, XmasCampaign.class));
    }  else {
      // Fall back to the main activity
      startActivity(new Intent(context, MainActivity.class));
    }
  }
}

Deep linking is the action of providing personalised content to a user when they open a mobile app, or taking them to a specific location within the app. By doing this, you can provide your users with a quality user experience that greatly enhances their interaction with the app.

  • Opening the app in a browser or SMS will open the app directly if it is installed, otherwise it leads to a download. For Android, the main technology involved here is deeplink, which can also be seen simply as scheme.
  • In fact, AppLink is a special Deeplink, except that it has an additional mechanism similar to verification, if the verification passes, it will be set to open by default, if the verification does not, it will degrade to deeplink. “true”.
  • Also in WeChat, you can make this operation. If the user has already installed the app, clicking on the jumping app will open the app and jump to the corresponding page via App Store, which is also a kind of AppLink.

To sum up, Deeplink, also known as deeplink technology, refers to the technology of clicking on a link in an app/sms/advertisement to jump directly to the specific location of the target app, which breaks the barrier between the website and the app and becomes a bridge between the website and the app. Developers can use deeplink not only to jump from websites to apps, but also to jump from multiple platforms (QQ, WeChat, Weibo, Twitter, Facebook, SMS, major browsers, etc.) to specific pages within apps. For example, if a user sends a link to a detail page in an e-commerce app to other friends and family via SMS, the user can click on the link in the SMS to open the corresponding H5 page and then jump directly to the specified detail page in the e-commerce app, instead of the app home page. If the user has not installed the app, then they will be redirected to the app download page. Deeplinking technology not only enables the rapid restoration of scenes and shortens the user’s path, but more importantly, it can be used to promote new apps and reduce user churn.

Deep Linking is just a concept that refers to a link to another website/app and a page directly within it. Deep Linking gives the user a very smooth browsing experience, especially in the web world where Deep Linking is very easy to implement.

URI Scheme, Universal Links, Android App Links, and Chrome Intent are all attempts to solve the problem of Deep Linking from a web page to an app.

Each of these implementations has its own platform and browser, and compatibility with most browsers requires different policies to be applied depending on the User Agent. The behaviour of these implementations is also inconsistent and it may be necessary to work with product requirements to determine which implementations to combine. These implementations are described in more detail below, with the following table providing an overview of the differences between the implementations.

Technology Universal Link Android App Link URI Scheme Chrome Intent
Platform Requirements >= iOS 9 >= Android 6 Chrome 1 < 25, iOS Chrome 1 >= 25
No performance installed Open Web page Open Web page An error occurred Can open Web page
Can you not jump No No Yes Yes
Can I go to a download page can can can can
iframe triggering not supported not supported Chrome 1 <= 18, iOS < 9 not supported
link format 2 normal URLs normal URLs custom protocol URLs intent protocol URLs

JavaScript get success or not

All of the above must be requested from the page (except for iframes in certain cases) and there is no JavaScript API available. In theory there is no callback for the result of a call-up.

In practice, however, it is possible to use setTimeout to check whether the page is still running and whether it has been interrupted. The principle is that if the page cuts away (which means it was successfully raised), the trigger point for the setTimeout callback will be delayed. This approach is not accurate, but it is the only one available.

  • If it is judged to be a successful call-up, it must be a successful call-up.
  • If the call-up is judged to be a failure, it is possible that the call-up will be successful.

That is, there is a high probability of False Negative, but not False Positive.

About domestic browsers

This section discusses the performance of these three browsers: UC, WeChat, and QQ, which hold most of the market share outside of the system browser and perform surprisingly consistently.

  • They block all page launches under Android. Users need to be prompted to open from the system browser.
  • For iOS they block URI Scheme and neither pop-ups nor call-ups. For Universal Link they open the web page directly without raising it.

Where the UC browser is on iOS < 9, attempting a URI Scheme bring-up is likely to crash straight away. Due to browser compatibility issues and the fact that the app installation rate is unlikely to be 100%, the success rate is generally very low, especially on Android.

Deferred Deep Linking

Compared to deeplink, it adds 2 functions to determine whether the APP is installed and user matching.

  • Determine whether the APP is installed when the user clicks the link, and guide the user to jump to the app shop to download the app if the user has not installed it.
  • User matching function, when the user clicks on the link and when the user launches the APP, the user Device Fingerprint (device fingerprint information) is transmitted to the server for fuzzy matching on these two occasions respectively, so that when the user downloads and launches the APP, the corresponding specified page is opened directly.

With the above 2 technical solutions, not only.

  • allows the shared user to return to the APP faster and more easily and to the designated active page, but also.
  • users who have not installed the APP can be guided to download it, and
  • The relationship chain between the sharer and the sharee will be recorded through the device fingerprint information, and the corresponding reward will be given in the business scenario.

Deferred Deeplink can first determine whether the user has already installed the App, and if not, it will first lead to the App shop to download the App, and then jump to the specified App page in Deeplink after the user has installed the App.

sobyte

In addition to the above-mentioned Deeplink operation, Deferred Deeplink is more effective in targeting people who have not installed the app. For example, if a user in a shopping app shares a product they like with their social account, if they do not use Deferred Deeplink, their friends may not find the product they shared with them after they clicked to download and install the app. This results in a high churn rate.

Any matching problem can be translated into the problem of getting a unique tag. It’s easy to think of session and cookies in http, but the sandbox model of mobile phones blocks data sharing between apps. This means that the app’s cookies are separate from the mobile browser’s cookies and are not interoperable.

Solution 1: By device unique ID

This solution is only suitable for the scenario where one app is diverting traffic to another app.

Solution 2: via IP address + device information (device size, OS, etc.) + time limit (e.g. 10 minutes)

sobyte

Solution 3: Clipboard Solution

The H5 page automatically calls the clipboard to copy the current user channel ID when clicking on the download, and the APP calls the clipboard each time the content format matches then the user and the H5 user are identified as the same user.

Third party libraries

Third party services that support deep linking and deferred deep linking, such as AppsFlyer and Branch. There is a lot more involved, so I won’t expand on it here. A separate in-depth analysis will follow later.