iOS H5打开App(通用链接)

入秋了,路上会遇到用小贩用小货车拉着卖芒果,和去年一样,我会停下急匆匆的脚步,买几个。一则自己爱吃芒果不过敏,二则品尝下是否和去年一样熟悉的味道。

很多时候可能都希望在浏览器,微信里面点击一个H5链接或按钮,之后直接打开App跳到App里面指定的页面。

  • safari,chrome,UC,搜狗,opera Mini等浏览器-----》唤醒App。
    用户通过浏览器地址栏输入官网地址,或商品地址打开App里面指定页面。若手机内未安装App则引导用户跳入Apple Store下载页。(本来准备举美团的例子,结果美团变成了小程序,那就某东吧)。
    在浏览器中输入商品地址:

手机安装了某东。

2.gif

手机未安装某东。

4.gif
  • 微信,QQ,微博-----》唤醒APP。
    用户通过某APP分享了一条链接至微信,QQ或微博,用户点开该链接后,会引导用户B打开该APP或者下载该APP。

在微信里面点击的分享的商品:

手机安装了某东。

1.gif

手机未安装某东。

3.gif
  • 短信、备忘录,邮件-----> 唤醒APP。
    用户收到一条推广短信,在短信里面点击链接跳入App里面或下载App页。

如何实现上面的场景呢?分为iOS9.0以前和iOS9.0以后。

1.iOS9.0以前只有一种实现方式,scheme方式。若安装App则跳入指定页面,则scheme后面加参数:”taobao://item.taobao.com/item.htm?id=“。若未安装跳到下载页引导用户下载安装。

let link = "taobao://item.taobao.com/item.htm?id=" + id,
    fallback = "itms-apps://itunes.apple.com/cn/app/" + appId;
// 尝试呼起 App
location.href = link;
// 3s 后未能呼起则跳转 App Store
setTimeout(() => location.href = fallback, 3000);

浏览器如何知道手机是否安装了App呢,通过设置延时。

  • setTimeout的实现过程:
    浏览器尝试打开URL scheme并记录时间点t1,在2秒计时后,检查当前时间t2,如果t2-t1 > 2200ms,说明唤起app成功(唤起app会是浏览器的定时器延后执行),如果t2-t1 < 2200ms,可能没有安装app,可以引导用户进入下载页。


    5.gif

    6.gif
var openTime = +new Date();
window.location.href = 'wzry://videolists.show/mark/penta_kill?num=1'
var timer = setTimeout(function () {
    if ((new Date()) - openTime < 2200) {//加了200ms基准误差
        window.location.href = 'you app download page';
    }
    if ((new Date()) - openTime > 2200) {
        clearTimeout(timer);
    }
}, 2000);

  • setInterval实现过程:
    原理上跟setTimeout相似,方法上换成设置一个比较小的时间间隔(例如20ms),运行多次(例如100),比较运行完100次的总耗时与20*100的时间差。逻辑判断同setTimeout。
var limit_num = 100;
var openTime = +new Date();
window.location.href = 'wzry://videolists.show/mark/penta_kill?num=1'
var timer = setInterval(function () {
   if(limit_num > 0){
        limit_num--;
   }else{
        if ((new Date()) - openTime < 2200) {//加了200ms基准误差
            window.location.href = 'you app download page';
        }
        clearTimeout(timer);
   }
}, 20);

iOS9.0以后有两种方式,scheme和universal link(后面单独说)。重要的事情说三遍,iOS9.0以后还是可以用scheme,只是在iOS9上,iframe方案变得不可用,在打开自定义URL scheme时,会弹出对话框,询问是否用 xx应用来打开。若未安装App则会显示“safari打不开该网页,因为网址无效”。(可以通过直接跳转:点击链接或者修改window.location。<a href="schemeUrl">唤醒你的APP</a>,window.location.href = schemeUrl)

针对微信,就不区分iOS9.0之前和之后了,因为微信有白名单,白名单里面只包含50个App的url scheme。怎么查看呢。通过Apple configuration 2能够查到,具体请看文章

白名单如下:在这个 plist 文件中找到白名单很简单,因为微信已经达到了49个的上限,一个很扎眼的 “(49 items)” 的 “Array” 项 LSApplicationQueriesSchemes 就是我们要找的白名单了。我们可以看到诸如腾讯新闻 (qqnews), 腾讯视频 (tenvideo2) 都是在白名单内的。


8.gif

从微信里面打开分享的网页跳入App里面有三种(腾讯应用宝,通用链接,引导用户浏览器打开)解决办法:

1.使用腾讯应用宝。

使用它颁发给你的应用地址,向这个地址跳转,然后一切就交给微信了,直接无视微信什么的,直接带你飞到app内。具体可看腾讯应用宝Applink接入文档。举个例子,网易新闻。从网易新闻分享一条链接到微信,在微信里面点开链接。

  • 若安装了微信。直接打开到网易新闻App对应链接。
7.gif
  • 若未安装微信。腾讯应用宝跳到Apple Store进行下载。有趣的是下载完成后,点击打开后还能跑到对应链接。这是为什么呢。因为在微信里面点击打开按钮时,粘贴板上粘贴了该条链接的信息,跳入网易新闻之后,和淘宝一样监听到粘贴板上面的内容后跳到指定页面。
8.gif
11.gif
12.gif

2.Universal Links(通用链接)。

  • 在2015年的WWDC大会上,Apple推出了iOS 9的一个功能:Universal Links通用链接。如果你的App支持Universal Links,那就可以访问HTTP/HTTPS链接直接唤起APP进入具体页面,不需要其他额外判断;如果未安装App,访问此通用链接时,可以一个自定义网页。

优点:

  • 唯一性:不像自定义的scheme,因为它使用标准的HTTP/HTTPS链接到你的web站点,所以它不会被其它的app所声明.另外,Custom URL scheme 因为是自定义的协议,所以在没有安装 app 的情况下是无法直接打开的,而Universal Links本身是一个HTTP/HTTPS链接,所以有更好的兼容性;
  • 安全:当用户的手机上安装了你的app,那么iOS将去你的网站上去下载你上传上去的说明文件(这个说明文件声明了APP可以打开哪些类型的http链接)。因为只有你自己才能上传文件到你网站的根目录,所以你的网站和你的app之间的关联是安全的;
  • 可变:当用户手机上没有安装你的app的时候,Universal Links也能够工作。如果你愿意,在没有安装APP的时候,用户点击链接,会在safari中展示你网站的内容;
  • 简单:一个URL链接,可以同时作用于网站和app,可以定义统一的web-native协议;
  • 私有:其它APP可以在不需要知道是否安装了的情况下和你的APP相互通信;

缺点:
只支持iOS9及以上系统;当使用Universal Link打开APP之后,状态栏右上角会出现链接地址,点击它会取消Universal Link,需引导用户重新使用Safari再次打开该链接,弹出Safari内置APP广告条,再点击打开重新开启Universal Link。

本来一般公司会有一个官网域名https://www.aaaaa.com/,你必须找运维同学开一个专门用来制作通用链接的域名https://oap.aaaaa.com,然后上传apple-app-site-association的json文件到.well-known和根目录,具体如下面的步骤:

1.创建一个json格式的命名为apple-app-site-association文件,注意这个文件必须没有后缀名,文件名必须为apple-app-site-association上传到https.

{
    "applinks": {
        "apps": [],
        "details": [
            {
                "appID": "ABCD1234.com.aaa.app", 
                "paths": [ "/info/*", "/mobile/*"]
            },
            {
                "appID": "EFGH5678.com.bbb.app", 
                "paths": [ "*" ]
            }
        ]
    }
}

说明: appID = teamId.yourapp's bundle identifier
paths = APP支持的路径列表,只有这些指定的路径的链接,才能被APP所处理,大小写敏感。举个例子,如果你的网站是oap.aaa.com,你的path写的是"/info/*",那么当用户点击www.aaa.com/info/<path>?<params>=<value>,就可以唤醒APP了,相反www.aaa.com/other就不会。此外Apple为了方便开发者,提供了一个网址来验证我们编写的这个apple-app-site-association是否合法有效,这个网址经过测试后有的有效果有的没有效果。下图是输入oia.zhihu.com之后的效果。

WX20181219-193247@2x.png

2.激活Xcode工程中的Associated Domains能力,在其中的Domains中填入你想支持的域名(这里不是随便填的,是可以支持你需要的Universal Links的域名), 必须以applinks:为前缀,例如:applinks:oap.aaaaa.com将会在合适的时候,从这个域名请求apple-app-site-association文件。注意:当你打开Associated Domains后,Xcode会在你的工程中添加.entitlements文件,并且登录开发者中心,可以看到Associated Domains处于Enable状态。

WX20181219-202128@2x.png

3.在AppDelegate里实现如下代理方法:

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *))restorationHandler {
    // NSUserActivityTypeBrowsingWeb 由Universal Links唤醒的APP
    if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
        NSURL *webpageURL = userActivity.webpageURL;
        NSString *host = webpageURL.host;
        if ([host isEqualToString:@"yohunl.com"]) {
            //进行我们需要的处理
        } else {
            [[UIApplication sharedApplication]openURL:webpageURL];
        }
    }
    return YES;
}

至此APP已经开启Universal Links,可以通过链接唤醒APP,并跳转至指定页面了。流程如下:


WechatIMG433.jpeg

4.跨域。假设当前微信浏览器中话题详情页面的 URL 为 "www.domain.com/XXX",底部“打开App”按钮对应的链接URL为 "www.domain.com/YYY",但由于www.domain.com/YYY不在配置的域名oap.domain.com的域名下,因此实际不能完成跳转。必须写点击事件跳转到与applinks中添加的域名相同的页面例如oap.aaaaa.com/info/download.html(要跨域),在微信中就直接跳转到了我们的app中了!

注:用于跳转打开app的域名需要支持https,如果是一级域名页面有个按钮,点击按钮跳转二级域名来打开app,那么二级域名需要支持https。这里DEMO的二级域名不支持https,所以采用的方案是二级域名跳转到一级域名来打开APP。

5.从微信跳转到app的时候,屏幕右上角还有个 "xxx.xx" 的小箭头:点击该箭头,会在Safari中打开该页面。此时再回到微信浏览器中点击 "打开App"按钮,神奇的事情出现了:无法跳转到app!!!

解决方案:在Safari中打开该页面,将网页拉倒最顶部,会出现一个悬浮框,点击悬浮框中的打开按钮,又跳回到app中打开指定页面,此时再回到微信浏览器中点击 "打开App"按钮,又能正常跳转到app了。
Universal Links 功能的接入其实相当于给某些 URL 添加了一种新的打开方式,但是旧的通过浏览器打开 URL 的方式仍然可用,当点击右上角跳转箭头时,相当于又设置这些特定 URL 的默认打开方式为浏览器而非 web,因此一键跳转功能此时会失效。反之通过点击顶部 "打开" 按钮,相当于又将这些特定 URL 的默认打开方式修改为 app ,一键跳转功能恢复正常。
在Safari中打开页面刚进入时,横条是隐藏的,一定要将页面拉到最顶部时才能显示。

3.引导用户去浏览器打开。微信已经屏蔽了通用链接,所以大多数App都做了引导用户去浏览器打开。下一篇文章介绍微信屏蔽通用链接

4.gif
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容