iOS通用链接(Universal Links)配置
Universal Links
在app
开发中我们经常需要从浏览器,Safari中去唤醒app
,iOS 9
之前我们通过配置scheme
从而实现这种跳转,但是这种方式需要提前判断系统中是否安装了能够响应对应scheme
的app
,这种方式在微信中是被禁用的。
Universal Links
是iOS 9
推出的一项功能,我们可以通过配置Universal Links
使用户能够通过一个链接进入app
或者指定页面,这个不会被微信禁用。
配置
-
首先我们需要有一个支持
Https
的域名,必须支持Https
. -
创建一个内容为
Json
格式的文件,文件名为apple-app-site-association
,没有后缀名,文件内容大体如下:{ "applinks": { "apps": [], "details": [ { "appID": "2DNT4K53X5.com.apple.wwdc", "paths": [ "/videos/wwdc/2015/*", "/wwdc/news/"] }, { "appID": "ABCD1234.com.apple.wwdc", "paths": [ "*" ] } ] } }
注意⚠️:
appID组成:TeamId.your app’s bundle identifier。这里我随意填的,
2DNT4K53X5
表示你app
的TeamId
,com.apple.wwdc
表示app
的bundle identifier。其中TeamId
你需要登陆相关开发者账号,到Account - Membership
中去获取,如下图:
![](https://img.haomeiwen.com/i1493072/054ef1a9957a304e.png)
paths组成:设定你的app支持的路径列表,只有这些指定的路径的链接,才能被app所处理。*
的写法代表了可识别域名下所有链接。
- 将这个文件上传到你的域名对应的根目录或者
.well-known
目录下(需要后端配合),这样苹果将会在合适的时候,从该域名请求这个文件。我们可以自己测试,即打开你的域名/apple-app-site-association
,看看我们能不能够下载到对应的文件。 - 然后我们需要在
app
中进行相关配置。之前我们需要在对应App Id
的Application Services
列表中加入Associated Domains
,使它变成Enabled
。现在Xcode
会帮我们自动配置,我们只需要在项目中加入Associated Domains
,然后在Domains
中加入相应链接,如下图:
![](https://img.haomeiwen.com/i1493072/b87eff80cf417e03.png)
![](https://img.haomeiwen.com/i1493072/12faab79c1a91c1a.png)
![](https://img.haomeiwen.com/i1493072/46372e17350a43c9.png)
注意⚠️: Domains
中加入的链接,必须以 applinks:
开头,然后去除你的域名前的Https
以及最后的/
,例如你的域名是https://www.apple.wwdc.com/
,那么Domains
中加入的就是applinks:www.apple.wwdc.com
。
验证配置
配置一个该域名下可以访问的链接地址,然后复制该链接到Safari
中直接访问,然后在出现的网页中下拉,当出现在“XXX”App中打开
即可,如下图:
![](https://img.haomeiwen.com/i1493072/88970e4e759c8fda.png)
注意⚠️: 只有当前Webview
的url
域名,与跳转目标url
域名一致时,Universal Link
才会生效。
进入app后对链接进行处理
当用户点击对应的链接时,会直接进入app
,如果我们需要监听链接并做出不同的处理,我们就需要在AppDelegate
中实现对应的方法,否则就是直接进入app
。
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler{
NSLog(@"userActivity : %@",userActivity.webpageURL.description);
if([userActivity.webpageURL.description rangeOfString:H5_JumpApp_CourseMark].location != NSNotFound){
//相应处理
}
return YES;
}
注意⚠️: 该方法是在进入app
之后才会进行调用
微信相关配置
在使用旧版本微信SDK
时,分享会出现未验证
现象。这时候需要我们更新SDK
并进行相应的Universal Links
配置。
![](https://img.haomeiwen.com/i1493072/e52ff07d97e2085b.png)
项目更新对应的微信SDK
pod 'WechatOpenSDK', '~> 1.8.7.1'
或者
直接导入相关SDK。
微信后台加入Universal Links
配置
在微信后台加入你设置的域名配置,如https://www.apple.wwdc.com/
![](https://img.haomeiwen.com/i1493072/af8507685ec87509.png)
app设置
-
Info.plist
和Setting的info
中LSApplicationQueriesSchemes
中加入weixinULAPI
![](https://img.haomeiwen.com/i1493072/1e43f0dd341652d0.png)
![](https://img.haomeiwen.com/i1493072/f4f47c7478a7f5b7.png)
微信提供了检测的方法
//调用自检函数
[WXApi checkUniversalLinkReady:^(WXULCheckStep step, WXCheckULStepResult* result) {
NSLog(@"%@, %u, %@, %@", @(step), result.success, result.errorInfo, result.suggestion);
NSLog(@"123");
}];
![](https://img.haomeiwen.com/i1493072/4fab11182fb0ec97.png)
[图片上传中...(iOS通用链接(UniversalLinks)配置_11.png-e0f8d4-1590471612390-0)]
注意⚠️: 通过自检方法我们能够知道Universal Links
配置是否成功。另外未验证问题不是实时更新的,你会发现你更新了SDK
也不会立刻生效,需要等待从未验证列表
中移除为止。
最明显的就是效果就是只有第一次会通过微信验证,后面就不会再调用微信验证了。
![](https://img.haomeiwen.com/i1493072/5e33e5ad141060e7.png)
注意⚠️:接入微信之后必须- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
方法中加入[WXApi handleOpenUniversalLink:userActivity delegate:self]
,否则会导致微信的回调-(void)onReq:(BaseReq*)req
不执行。
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler{
NSLog(@"userActivity : %@",userActivity.webpageURL.description);
if ([userActivity.webpageURL.description containsString:kAppID_Weixin]) { // 微信调用
return [WXApi handleOpenUniversalLink:userActivity delegate:self];
}else if([userActivity.webpageURL.description rangeOfString:H5_JumpApp_CourseMark].location != NSNotFound){
//相应处理
}
return YES;
}