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

来源:互联网 发布:php后台admin 编辑:程序博客网 时间:2024/06/05 07:24

一、实现大致思路

前提条件:
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://tool.chinaz.com/tools/urlencode.aspx
    )之后再拼接到http://blog.joeychang.me/index.html?之后,生成长链接,再[短链接处理](http://dwz.wailian.work/
    )生成短链接。短链接即可分享。

  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>
0 0