什么是Universal Link(通用链接)
背景介绍
Universal Link 是苹果在 WWDC 2015 上提出的 iOS 9 的新特性之一。此特性类似于深层链接,并能够方便地通过打开一个 Https 链接来直接启动您的客户端应用(手机有安装 App)。对比以往所使用的 URLSheme,这种新特性在实现 web-app 的无缝链接时,能够提供极佳的用户体验。使用前请阅读苹果官方文档 - Support Universal Links。
由于苹果 iOS 13 系统版本安全升级,微信 SDK1.8.6 版本要求支持 Universal Links 方式跳转,以便进行合法性校验,提升安全性。详情请参考微信官方文档 - iOS 接入指南特点
Universal Link 可以无缝链接到 app 或网页,主要应用场景有内容分享和广告投放。它有如下特点:
如果安装了 app,会直接打开 app,并定位到内容页;
如果没有安装 app,使用浏览器打开该链接;运行原理
- 当 App 初次安装后或者更新版本后的第一次启动(第二次启动就不会),向工程配置的 applinks: 的域名请求 apple-app-site-association 配置文件;
- App 自动的将 apple-app-site-association 配置文件向 iOS 系统配置;
-
当任何 WebView 发起 UniversalLink 的 url 的时候,系统遍历注册过的通用链接,如果命中则直接打开 App 触发 Delegate 方法;如果没命中,WebView 继续跳转加载 url。
以上都是系统默默替你做的,我们要做的就是确保配置的正确性。
一、配置app开发者账号
1.首先登录 苹果开发者网站 ,打开Associated Domains
2.Certificates, Identifiers & Profiles
下的Identifiers
找到要配追的Identifiers
点进去
3.打开Associated Domains
然后保存
- 更新Profile文件
如果我们使用自动的,可以忽略这一步,手动的创建的证书,选择对应的配置文件,点击Edit进入修改页,直接点击Save,保存后点击Download下载并打开
二、配置工程
在项目中添加 Associated Domains
打开项目Target -> signing & Capability -> + Capability -> Associated Domains
填写域名,将https://替换为applinks:
三、创建apple-app-site-association文件
创建一个纯文本,文件名字为apple-app-site-association的文件,不能有后缀
编辑文件内容
{
"applinks": {
"apps": [],
"details": [
{
"appID": "3D*****U3T.com.xxx.xxxProject",
"paths": [ "*" ]
}
]
}
}
"appID": "TEAM_ID.BUNDLE_ID" 格式含义:TEAM_ID是你的苹果开发者账号团队ID,BUNDLE_ID是你的应用的Bundle ID
paths数组指定了哪些网站路径将与你的应用关联。如果想要关联整个网站,可以使用"*"
上传此文件到服务器
文件可以直接放在服务器的根目录或者.well-known目录下(在这两个目录下让nginx 处理 return json string也可以)
https://www.xxx.rent/apple-app-site-association
https://www.xxx.rent/.well-known/apple-app-site-association
可以通过浏览器访问这两个路径,看看有没有下载文件或者返回json
四、验证Universal Link链接是否配置正确
打开safair浏览器
输入https://www.xxx.rent/xx/xx,出现在App中打开,就说明我们配置成功了
在App代理中接收
(注:要用打出的testflight包或上传到appstore包验证,因为涉及到证书与apple-app-site-association 关联,自己build出的测试包应该是无效的)
AppDelegate {
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb, let url = userActivity.webpageURL else {
return false
}
return handleURL(url)
}
@discardableResult
private func handleURL(_ url: URL) -> Bool {
return false
}
}