Universal link通用链接 (activity iOS9.0)
-
唯一性: 不像自定义的URL Scheme,因为它使用标准的HTTPS协议链接到你的web站点,所以一般不会被其它的APP所声明。另外,URL scheme因为是自定义的协议,所以在没有安装 app 的情况下是无法直接打开的(在Safari中还会出现一个不可打开的弹窗),而Universal Link(通用链接)本身是一个HTTPS链接,所以有更好的兼容性;
-
安全:当用户的手机上安装了你的APP,那么系统会去你配置的网站上去下载你上传上去的说明文件(这个说明文件声明了当前该HTTPS链接可以打开那些APP)。因为只有你自己才能上传文件到你网站的根目录,所以你的网站和你的APP之间的关联是安全的;
-
可变:当用户手机上没有安装你的APP的时候,Universal Link(通用链接)也能够工作。如果你愿意,在没有安装你的app的时候,用户点击链接,会在safari中展示你网站的内容;
-
简单:一个HTTPS的链接,可以同时作用于网站和APP;
-
私有: 其它APP可以在不需要知道你的APP是否安装了的情况下和你的APP相互通信。
-
(BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler {
if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
NSURL *url = userActivity.webpageURL;
if (url是我们希望处理的){
//进行我们的处理
}
}
return YES;
}
apple-app-site-association文件名固定,不能修改,不能加后缀; 必须支持https且不能重定向,该文件放在指定域名(Xcode工程中Associated Domains配置的域名)下的/.well-known/目录下。
{
"applinks":{
"apps":[],
"details":[
{
"appID":"9JXXXXXXNQ.com.XXXX.test",
"paths":["/dgtest/*"] //只要链接中包含/dgtest/就可以唤起app
}
]
}
}
["*"] 调起https: //mbankshare.XXXX.cn就可以启动App
["/dgtest/*"] 调起https: //mbankshare.XXXX.cn/dgtest/* 就可以启动App
appID为teamID.BundleID,path是设置哪些路径可以唤起APP。
paths 参数
这个 paths 路径的更多限制规则可以参考下面:
-
使用*指定整个网站
-
包含特定的网址(例如/wwdc/news/)以指定特定的链接
-
附加到特定的网址(例如 /videos/wwdc/2015/ )以指定网站的一部分
-
除了用于匹配任何子字符串之外,您还可以 ? 用于匹配任何单个字符。您可以将两个通配符合并在一个路径中,例如 /foo/ /bar/201?/mypage
-
路径字符串的开头添加 NOT 指定不应作为通用链接处理的区域,例如 "paths": [ "/videos/wwdc/201?/" , "NOT /videos/wwdc/2010/"]
注意:app只有在第一次启动时才会拉取该文件,除非app更新或重新安装,否则第一次拉取后不再拉取该文件。
只有当前 webview 的 url 域名,与跳转目标 url 域名不一致时,Universal Link 才生效。
网页的domain是www.lanxin.cn ,那工程中配置的domain就不能是www.lanxin.cn,否则跳转失败
如果有多个相同通用链接配置的 App,且 target 是 iOS13、tvOS 13 和 macOS 10.15 及以上系统,可以使用 ** appIDs** 来减小该文件的大小,该键的值是一个App 标识符数组。如果需要支持 iOS 12、tvOS 12或更早版本,则应该继续为每个 App 使用appID。
// Your apple-app-site-association File
{
"applinks": {
"apps": [],
"details": [
{
"appIDs": [ "ABCDE12345.com.example.app", "ABCDE12345.com.example.app2" ]
"paths": [ "/path/*/filename" ]
}
]
}
}
{
"applinks":{
"apps":[],
"details":[
{
"appID":"9JXXXXXXNQ.com.XXXX.test",
"paths":["/dgtest/*"] //只要链接中包含/dgtest/就可以唤起app
},
{
"appID":"9JXXXXXXNQ.com.XXXX.test2”,
"paths":["/dgtest/*"] //只要链接中包含/dgtest/就可以唤起app
}
]
}
}
注意:
不同的开发者账号,appid要注意区分;如果Xcode设置的domain不一样,那对应的apple-app-site-association文件也要放在domain的根目录下。
苹果是根据域名下的paths处理要打开的应用的,所以要避免相同的paths对应多个appID
多个APP方案:
1、如果domain不同,需要配置多份apple-app-site-association文件,每个文件里的details只需要添加一个APP信息即可
2、如果domain相同,配置一份apple-app-site-association文件,上传到同一根目录下,文件的details里填写多个APP信息,例如:
{
"applinks":{
"apps":[],
"details":[
{
"appID":"M9N2NBY3KD.com.test.dev",
"paths":["/qq_conn1/", "/wechat1/"]
},
{
"appID":"4X3EKPR8EQ.com.apple.dev",
"paths":["/qq_conn2/", "/wechat2/"]
},
{
"appID":"4X3EKPR8EQ.com.thk.dev",
"paths":["/qq_conn3/", "/wechat3/"]
}
]
}
}
注意:
同一个domain下,三个APP的paths不要相同,如果相同,那么h5链接就不能保证打开的APP是否为指定APP!appID是为了区分不同的domain,paths是为了区分同一个domain下不同的APP!
常见问题:
备忘录和safari中都可以打开app,怎么分享到其他app里面就不行了?
未跨域导致的,如:分享到微信的链接是www.mydomain.com/share.html,…
跨域的意思是说,通用链接 和 调用通用链接的网页不要使用同一域名。
即如果通用链接域名为www.mydomain.com,则通用链接所处的网页域名就不能是www.mydomain.com。
微信已经禁用了Universal Link(通用链接)
iOS13中在safari中可以打开相应APP,但是从微信或其他APP中点击去safari怎么就打开了别的APP?
在iOS13之前在其他APP去safari中打开Universal Link(通用链接)系统匹配域名是全匹配,而在iOS13之后规则发生了变化,猜测是包含关系。比如在iOS13之前,如果Universal Link(通用链接)为w.mydomain.com那么在微信或者其他APP访问www.mydomain.com然后点击去safari打开则不会拉起相应APP,而在iOS13则会拉起相应APP。
而在safari中输入的链接则依然和iOS之前一样,只有www.mydomain.com才会提示打开相应APP。
待完成:
-
中间页是否展示的逻辑:如果在网页中点击按钮或某个链接,可以直接跳转到目标app且已执行跳转操作,则不需要再跳转到中间页;否则,h5通过nginx打开中间页。
-
由于存在定制包,且域名各不相同,H5需要在无法跳转app时展示不同的中间页(域名:中间页)。方案:
-
-
维护一套映射关系;中间页部署在蓝信自己的域名下,中间页根据不同的域名提供不同的内容展示,比如客户端名字,并且可以拿到app的下载地址和跳转客户app的universal link。涉及到网络请求。存在问题:客户的app不能访问外网,该方案行不通。
-
网络请求
-
中间页部署在各自的universal link域名下,h5就不需要通过映射关系来展示中间页,但如果中间页中支持手动跳转至app的功能,那么在第三方应用的浏览器里则无法跳转,因为非跨域情况下,不支持跳转app,此时只能通过提示用户在系统浏览器里打开网页,才可以跳转至app。
-
-
鉴于跨域问题,在第三方app中,当前打开的网页域名不能和universal link域名一样,否则在第三方应用中无法跳转到目标app。非系统浏览器展示中间页的时候直接提示用户在系统浏览器中打开(universal link域名和中间页域名相同的情况下)。
-
低版本兼容(域名不变的情况下需要兼容;域名变更则无需兼容,旧版直接跳转到中间页):新增path,例如:/lxlinkopenurl/,新版universal link中域名后面的path为/lxlinkopenurl/。可不可以新增一个通配符*呢?不可以!因为如果新版app(域名不变,例如通版蓝信,以下均以通版蓝信举例)配置了通配符,那旧版本所有定制包在打开universal link时,不确定是跳转到通版蓝信,还是他们自己的app。
在第三方应用中直接点击universal link,跳转至中间页,如果中间页域名和universal link相同(无映射),则直接提示用户去系统浏览器打开。
疑问:
飞书链接:applink.feishu.cn/(path为通配符),在浏览器里打开时会直接弹框提示跳转app;钉钉也是如此,不同的是钉钉中间页为空白;
但蓝信链接:applink.dingtalk.com/xdev/,在浏览器里打开不会直接弹框提示跳转app。
因为他们配的path是通配符?
苹果官方文档:developer.apple.com/documentati…
注意:
1、host不能重定向,(重定向的话,浏览器中无法正常跳转,备忘录里可以)
2、iOS14之后,host必须是公网可访问地址
如果在开发调试中必须要使用内网,按如下步骤操作:
1.将Domain设置为如下格式:?mode=,官方文档:developer.apple.com/documentati…。例:
applinks:hosturl?mode=managed
applinks:hosturl?mode=developer
developer:可以使设备主动访问任何域名,包括不被系统信任的,前提是必须使用 development profile 运行app,adhoc、release都不支持
managed:不常用,主要用于企业级账号 MDM
developer+managed : 同时满足两种模式
2.手机【设置】-【开发者】打开Associated Domains Development开关
测试:
在浏览器中输入www.lanxin.cn/xdev/网址去请求,和通过window.location.href=‘www.lanxin.cn/xdev/’有什么区别?
在浏览器中输入www.xxx.cn/网址去请求,和通过wi…
提供一个中间页,三个按钮,提供跳转原生的功能,三个按钮分别打开以下链接:
www.lanxin.cn/xdev/chat/staff
该中间页配置在两个不同的域名下,一个配置在www.lanxin.cn/域名下,另一个配置在其他的域名下(只要能打开这个网页)
蓝信最终方案:
需要跨域,采用APPLink+scheme方式。
1、 在web页面(例:一个促销活动页面)点击按钮去跳转APP,接下来的操作分以下几种情况
1.1、同域名 + Safari:h5在当前页面调用universal link,打开下载页,在下载页通过scheme去打开APP(展示下载页)
1.2、同域名 + 第三方APP:h5在当前页面调用universal link,打开下载页,并在下载页提示去Safari打开 ,后续步骤同上(展示下载页)
1.3、跨域 + Safari:h5在当前页直接打开universal link地址(无需展示下载页)
1.4、跨域 + 第三方APP:h5在当前页打开universal link地址 (无需展示下载页)
即:只要是打开下载页,就在下载页通过scheme方式打开APP。
2、 在Safari或其他第三方APP中,直接点击universal link链接,接下来的操作分为以下几种情况
2.1、Safari:打开下载页,并自动调用scheme://打开APP (需要展示下载页)
2.2、第三方APP:打开下载页,提示用户去Safari打开,自动调用scheme:// 打开APP (需要展示下载页)