iOS 9 Universal Links 容易踩的坑

启用

Universal Links 功能的启用参考以下 2 个文档就行

https://developer.apple.com/library/ios/documentation/General/Conceptual/AppSearch/UniversalLinks.html

https://dev.branch.io/recipes/branch_universal_links/ios/

踩坑

下面是容易被坑到的地方和需要注意的点:

1.Universal Links 只有在 App 被新安装或者升级时才会重新检测一次配置,只对真机有效。不要试图连接任何的抓包工具通过安装证书的方式来解密查看它的 HTTPS 请求,该请求由 iOS 系统发起,不信任第三方证书,会导致请求失败。失败了会在 Device log 里有类似如下的输出:

Jan 25 13:43:45 GeXiao-666 swcd[2015] : 2016-01-25 01:43:45.871079 PM [SWC] ### Rejecting URL ‘https://www.gexiao.me/apple-app-site-association' for auth method ‘NSURLAuthenticationMethodServerTrust’: -6754/0xFFFFE59E kAuthenticationErr

2.必须是 HTTPS 的域名才支持。必须使用 Apple 要求的文件名和路径存放配置文件(https://www.gexiao.me/apple-app-site-association). 不同的子域名都是独立的,比如 blog.gexiao.me 和 www.gexiao.me 必须分开处理。但是有一个例外,Apple 将 www. 二级子域名和裸域名(gexiao.me)视为内容一致,所以如果有论坛同时支持 www. 子域名和裸域访问,请保证这两个 URL 路径都能正确获取到同样的配置文件。

3.必须设置 response 的 Content-Type 为 application/json

apple-app-site-association 文件的明文内容格式如下,其中的 paths 可以设置到具体路径并支持 ? * 通配符,还支持一个奇葩的 “NOT” 标记,详细内容参阅前面的官方文档。

1
2
3
4
5
6
7
8
9
10
11
{
"applinks": {
"apps": [],
"details": [
{
"appID": "8LX3M43WHV.me.gexiao.me",
"paths": [ "/*" ]
}
]
}
}

使用 “/*” 是为了保证当 URL 中不含有 path 仅有域名(https://www.gexiao.me)时仍然可以支持。

appID 的值是 App Bundle ID 的 Prefix + App Bundle ID,官方文档中表述为”team ID and the bundle ID”含有歧义。

4.用 Safari 打开目标域名,或者在其他 App 里用 SFSafariViewController, WKWebView, UIWebView 打开目标域名,都可以达到效果。

5.iOS 原生的几个 App 有非常好的支持(Mail, Note, Message, Safari),其他 App 可能存在不完善的情况。

6.最简单的测试 Universal Links 是否生效的方法:在系统自带的 Note App 中保存域名,然后长按该域名,会有 sheet 提示 在 “XXX” 中打开。

7.在 Xcode 的项目文件里,如果新开启了 Universal Links,会自动生成一个 [projectname].entitlements 的配置文件,里面包含一个名为 com.apple.developer.associated-domains 的 Array,Array 的每个 list 是一个域名(applinks:www.gexiao.me),一定要手动将这个文件加入到想要的 Target 中。

8.响应的逻辑实现在 AppDelegate 里

1
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler

9.系统会记住用户最近的选择,导致 Universal Links 被停用:用户因为 Universal Links 跳转到我们的 App 里之后,status bar 右边有返回浏览器打开的面包屑选项,用户如果点击了这个选项,该 App 的 Universal Links 就自动停掉了。最简单的重新启用方式是在 Note / Message 里长按目标域名,并选择在 App 中打开,或者在 Safari 的页面里下拉,用 Smart App Banner 打开 App。

10.有一个简单的在线工具,可以检测目标域名的配置文件是否正确且看到配置文件的明文内容(自动解密 application/pkcs7-mime 类型):https://limitless-sierra-4673.herokuapp.com/

Apple 官方也有个大而全的在线工具,但不够细致 https://search.developer.apple.com/appsearch-validation-tool/

11.用 nginx 处理文件的 MIME Type 示例配置,在 server 的某个域名下针对这个文件处理:

1
2
3
location /apple-app-site-association {
default_type application/json;
}

12.Universal Links 的 Associated Domains 文档中并没有提到有数量上限,实测加入 1000 个域名后 iOS 也都会接受。但 iOS 是在 App 安装或更新时遍历发送请求去检测配置的,所以关联很多域名会让其在短时间内发起大量请求,如果网络状况不佳导致检测失败,那么这个 Associated Domain 就会被视为没有验证通过。

13.直接 Debug 安装是可以调试 Universal Links 的,但是更新相关配置后最好把原来的 App 先删掉彻底重装。非 App Store 渠道安装的,在 Safari 的Banner 里看不到应用的名字,参考 这条微博