通用链接(Universal Links)实践笔记

一、实现大致思路

前提条件:

  1. 支持https的服务器
    我使用的是阿里云服务器,ssl证书使用的是pianyissl.com的测试证书,可以免费使用三个月。配好证书,使用tomcat、nginx部署环境。
  2. 服务器绑定域名
  3. 在服务器根目录上传apple-app-site-association文件
    效果需要满足访问https:domain.com/apple-app-site-association 能够下载或者打开json内容

二、开发中我的问题

  1. 微信中点击打开App网页按钮,想一个链接同时兼容iOS 9以上及以下。iOS9以上,点击链接直接进入app指定页面,iOS9以下进入应用宝下载页面。开发中遇到问题,微信网页内使用js没有找到判断手机是否安装了app,导致在未安装app时候点击链接进入404页面,展示很不好。开始尝试将404页面重定向到应用宝下载app页面,这样又出现app安装时点击打开按钮无法启动app。后来想了一个方法,终于解决了问题。
    a. 初始通用链接这样写:
    https://joeychang.me/s?name=test&url=http://baidu.com&type=2
    这样可以实现通用链接,但是在iOS9以下及未安装app情况下,链接无效。
    b. 后改成这样https://joeychang.me/s.html?name=test&url=http://baidu.com&type=2
    https://joeychang.me/s.html文件执行js重定向,用户点击这个页面,跳转到应用宝下载页。这样可以兼容iOS9以下及未安装app情况。
    c. 再后来,为了和安卓统一,参数格式定为
    http://blog.joeychang.me/index.html?params={"type":"3","url":"http://baidu.com","name":"test"}
    进入index.html这个页面,js方法抓取到params,点击页面内打开按钮,将参数传递给app,从未进入特定页面。
    d. 为了处理特殊符号,将params={"type":"3","url":"http://baidu.com","name":"test"}进行urlEncode之后再拼接到http://blog.joeychang.me/index.html?之后,生成长链接,再短链接处理生成短链接。短链接即可分享。

  2. 从iOS 9.2开始,在相同的domain内Universal Links是不work的,必须要跨域才生效,我们实测值需要跨子域名即可,比如 m.domain.com 跳转 o.domain.com 是可以触发跳转App。

这个又踩到坑了,在这里费了好长时间,最后还是和同事商讨才找到的答案。
apple-app-site-association文件,s.html放在joeychang.me服务器根目录,是为同一个域名内,而打开app.html为微信内唤醒app过渡网页,这个放在blog.joeychang.me域名下,才成功跳转。开始同样放在joeychang.me域名下,怎么也启动不了,险些要放弃开发,后来换了下域名,问题解决。坑死人。

三、几点注意:

  1. apple-app-site-association文件不能带后缀,务必把".json"的后缀去掉!有些人的电脑是隐藏文件后缀的,这要格外注意;

  2. apple-app-site-association要传到域名根目录或者/apple-app-site-association目录下;

  3. 如果想测试这个功能,可以让后台搭一个测试服务器,并绑定域名,然后iOS这边通过host访问域名就可以了。注意"applink:"后面写的一定是域名,不能是IP;

  4. 抓包的结果显示,网络顺畅的情况下,应用会在在刚安装(不是打开)的时候会去applink中的地址下载apple-app-site-association文件,所以如果需要测试,请保证网络通畅;

  5. 当所有都准备好,需要测试该功能的时候,只需要在记事本或短信中输入App能识别的链接(例如:https://www.joeychang.me/s/oaze4qfl97hksef/IMG_0019%20%281%29.png?dl=0 ),然后直接点击或是长按就可以了,直接点的效果是跳转到你的App,然后右上角是“去网页”的箭头,长按的效果是弹出的菜单中第二项是“在'XXX'中打开”,这也代表着成功。直接在Safari中输入链接是无效的,必须从一处跳入才可以(比如上一级网页)。

  6. 苹果有个网址(这里)可以检测你的apple-app-site-association是否是有效的,准备好了可以测试一下。

  7. 测试的时候,建议使用dev证书打包,之后安装到手机上测试功能。未安装应用的情况下直接在手机上跑好像也是可以的,因为抓到过请求。

四、使用apple 的测试接口测试出现的问题:

苹果测试网站

校验时出现问题 Applinks validator “domain missing from entitlement”,查了下资料,有这样说的:

This is the "App Search API Validation Tool", not the "Universal Links Validation Tool" (which doesn't exist from Apple). The results from this tool have no connection to whether Universal Links work or not.

This tool causes a lot of confusion, because domains that definitely work with Universal Links (https://google.com, https://jet.com, for example) still throw errors. Officially, it is comparing your website's apple-app-site-association file to your app's listing on the App Store, so if the version of your app that is publicly available does not yet have Universal Links entitlements, that will cause these errors. However, Universal Links will still work fine with local builds.

If your links are correctly opening your app, there is probably no need to worry.

我的实践是,即使校验不通过,只有配置文件json格式正确,上传目录正确,就可以打开应用。我出现的问题,apple-app-site-association内容,bundle Id中的teamId写错了,导致很长时间没有找到出错原因。后来对比了下苹果开发者中心才发现问题所在。白白浪费了很多时间。

五、参考链接:

  1. Universal Links官方文档
  2. Universal Links – Make the Connection
  3. iOS Universal Links(通用链接) (很不错的教程)
  4. 突破微信跳转限制-Universal-Links那些坑

六、附打开app过渡页.html示例源码

<!DOCTYPE html">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width,minimum-scale=1.0">

    <body bgcolor = "#FFEEDD">
    <input type="text" id="acti">
        <p>下载页面<a href="javascript:;" onclick="open_iOS_App()">ios 点击链接</a></p>
 
    </body>

 <a href="" id="aaa"></a>

 <script type="text/javascript">

        var timeout;
        function open_iOS_App() {
            if (isWeiXin()) {
                open_App();
            }else{
                open_App();
                timeout = setTimeout('open_itunes()', 3000);
            };
        }

        function open_Android_App() {
            if (isWeiXin()) {
                open_android_weixin();
            }else{
                open_App_Android();
            };
        }
        
        function open_android_weixin() {
           var acti = document.getElementById("acti").value;
           var linkUrl = "xxxxxxxxxxxxx://utils?action=sendIntent¶ms=" + acti;
           var yingyongbaoUrl = "http://a.app.qq.com/o/simple?pkgname=com.xxxx.xxxxx&android_schema=" 
            + encodeURI(linkUrl);
           window.location = yingyongbaoUrl; 
        }

        function open_App() {

                     var ver = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/);  
                     ver = parseInt(ver[1], 10);  
                     if(ver<9)  
                     {  
                             if (isWeiXin()) {
                                open_weixin_App();
                             }else{
                                open_itunes();
                              }
                      } else{
                               var activity = document.getElementById("acti").value;  

                               document.getElementById("aaa").href = "https://joeychang.me/s.html?params="+ encodeURI(activity);

                               //  alert(document.getElementById("aaa").href);
                               // alert(activity);
                               document.getElementById("aaa").click();
                      } 
        }

        function open_App_Android() {
            var acti = document.getElementById("acti").value;
            window.location = "intent://xxxxxxxxx?params="+ acti +"#Intent;package=com.xxxx.xxxxx;scheme=xxxxxxx;launchFlags=268435456;end;";    
        }
        function open_itunes() {/* 打开app store */
            window.location="http://itunes.apple.com/cn/app/idxxxxxxxx"; 
        }
                function open_weixin_App() {/* 打开腾讯应用宝 间接跳转 */
                var acti = document.getElementById("acti").value;
            window.location="http://a.app.qq.com/o/simple.jsp?pkgname=com.xxxx.xxxxx&activity=" + acti; 
        }

        /*
            判断是否是微信浏览器
        */
        function isWeiXin(){
            var ua = window.navigator.userAgent.toLowerCase();
            if(ua.match(/MicroMessenger/i) == 'micromessenger'){
                return true;
            }else{
                return false;
            }
        }
        function linktoApp() {
                        var queryStr = decodeURI(window.location.search.substr(1));
                        var ua = navigator.userAgent.toLowerCase(); 
                        if (queryStr.indexOf("}") >= 0 && queryStr.indexOf("{") >= 0) {
                              var activity = queryStr.substring(queryStr.indexOf("{"), queryStr.lastIndexOf("}") + 1);
                              document.getElementById("acti").value = activity; 
                             if (/iphone|ipad|ipod/.test(ua)) {
                         // IOS
                         } else if (/android/.test(ua)) {
                        // Android
                                open_Android_App();
                         } else {
                                // 其他浏览器
                                window.location="http://a.app.qq.com/o/simple.jsp?pkgname=com.xxxxxxx.xxxxxxxx";
                             }
                         } else {
                              document.getElementById("acti").value = "参数格式错误"; 
                         }        
        }
        
        // 用js实现在加载完成一个页面后自动执行一个方法
        /*用window.onload调用myfun()*/
        window.onload=linktoApp;//不要括号
    </script>
</head>
<body>
</body>
</html>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容