前言
本文介绍Universal Links(通用链接)
是什么,有什么作用?以及具体做法。
一:Universal Links(通用链接)是什么,有什么作用?
iOS 9之前
,一直使用的是URL Schemes
技术来从外部对App
进行跳转,但是iOS系统中进行URL Schemes
跳转的时候如果没有安装App
,会提示无法打开页面
的提示。
iOS 9之后
起可以使用Universal Links
技术进行跳转页面,这是一种体验更加完美的解决方案。
简而言之: Universal Links
是从浏览器
或者网页
上打开链接跳转到手机上的app
。
- 我们在该链接域名根目录配置过的一个
链接
(直接跳转到我们app);也可以在该链接中放置对应的H5
页面(点击H5
页面按钮跳转到我们app)。- 当用户的点击该链接,只要手机中安装了支持该链接的
APP
就会直接进入到APP
中。如果没有安装APP
则会跳转到Safari
浏览器中,展示H5
页面。对用户来说则是一个无缝跳转的过程。
使用Universal Link(通用链接)跳转的好处???
1,
唯一性
: 不像自定义的URL Scheme
,因为它使用标准的HTTPS
协议链接到你的web
站点,所以一般不会被其它的APP
所声明。另外,URL scheme
因为是自定义的协议,所以在没有安装app
的情况下是无法直接打开的(在Safari
中还会出现一个不可打开的弹窗),而Universal Link
(通用链接)本身是一个HTTPS
链接,所以有更好的兼容性;
2,安全
: 当用户的手机上安装了你的APP
,那么系统会去你配置的网站上去下载你上传上去的说明文件(这个说明文件声明了当前该HTTPS
链接可以打开那些APP
)。因为只有你自己才能上传文件到你网站的根目录,所以你的网站和你的APP
之间的关联是安全的;
3,可变
: 当用户手机上没有安装你的APP
的时候,Universal Link
(通用链接)也能够工作。如果你愿意,在没有安装你的app
的时候,用户点击链接,会在safari
中展示你网站的内容;
4,简单
: 一个HTTPS的链接,可以同时作用于网站
和APP
;
5,私有
: 其它APP
可以在不需要知道你的APP
是否安装了的情况下和你的APP
相互通信。
支持Universal Link(通用链接)
先决条件:必须有一个支持HTTPS
的域名,并且拥有该域名下上传到根目录的权限(为了上传Apple指定文件)。
二:项目业务场景两种情况:
- 1,
APP
分享出一个链接到微信,微信上点击此链接,直接跳到APP
- 2,
APP
分享出一个链接到微信,微信上点击此链接,先打开一个网页,网页上有个按钮,点击按钮跳转到APP
。
三:配置步骤
- 1, 微信开发者平台(比如分享到微信)
- 2, 配置指定
apple-app-site-association
文件- 3, 苹果开发者账号网站配置和项目配置
- 4, 需要去第三方平台设置 (比如友盟)
一:分享的平台配置(比如微信)
①微信开发者平台
在微信应用配置中就需要填写Universal Link
配置了 注意一定是: https:// 作为开头
,以/
结尾,中间就是在xcode
填写的域名
且不能带参数 例:
https://www.Share.com/
②要求在注册微信appid
时,必须要传入universalLink
,以前的方法在旧版本仍然可使用。所以就开始研究通用链接(Universal Link)的配置
[WXApi registerApp:@"APPID" universalLink:@"https://www.Share.com/"];
二:配置指定apple-app-site-association
文件
①apple-app-site-association
文件创建编辑其内容
需要创建一个apple-app-site-association
文件,必须命名为apple-app-site-association
,切记没有后缀。
终端创建:
touch apple-app-site-association
文件内添加json格式
数据,内容如下:
{
"applinks":{
"apps":[],
"details":[
{
"appID":"9JA89QQLNQ.com.apple.wwdc",
"paths": [ "*" ]
}
]
}
}
如果一个域名下面有多端APP,可写作
{
"applinks":{
"apps":[],
"details":[
{
"appID":"9JA89QQLNQ.com.apple.wwdc",
"paths": [ "*" ]
}
{
"appID":"47B89MSKWP.com.apple.xuem",
"paths": [ "/app/*", "/qq_conn/2222222/*"]
}
]
}
}
- 1,
apps
:是限制只能在这几个app
中使用, 基本是不填写,所以是空数组- 2,
appID
:为teamId.bundle identifier
形式,9JA89QQLNQ
就是teamId
,com.apple.wwdc
是项目identifier
。
登陆开发者中心,在Account -> Membership
里面可以找到Team ID
。- 3,
details
:数组中可以配置多个APP
的信息,如果公司内有多个APP
需要支持Universal link
,则可以直接添加多个- 4,
paths
:设定你的app支持的路径列表,只有这些指定路径的链接,才能被app所处理。*
的写法代表了可识别域名下所有链接- 5,
/app/*
是自己定义的路径;
/app/*
是自己定义的路径;
/qq_conn/22222222/*
需要根据QQ互联平台设置,22222222
是QQ互联后台
对应应用的APPID
。
如果上传人员给你的访问路径是:
https://www.baidu.com/.well-known/apple-app-site-association
或
https://www.baidu.com/apple-app-site-association
则:
微信开放平台的Universal Link填写是:https://www.baidu.com/app/
QQ互联平台的Universal Link填写是:https://www.baidu.com/qq_conn/22222222/
②上传指定文件
将这个文件上传到你的服务器
,可以将这个文件放到服务器的根目录
下,也可以放到.well-known
这个子目录下。这是为了苹果
能获取到你上传的文件。
必须支持HTTPS
协议,让我们请求 域名/apple-app-site-association
能请求到。因为没指定请求头的类型,所以请求下来的是个文件。
对应连接分别为
//xxx 为服务端的域名
https://xxx/apple-app-site-association
https://xxx/.well-known/apple-app-site-association
上传完后,让上传人员给你一个访问路径,先访问一下,看看是否能够获取到,当你在浏览器中输入这个文件链接后, 出现下图就可以了:
此外服务器上apple-app-site-association
的更新不会让iOS
本地的apple-app-site-association
同步更新,即iOS
只会在App
第一次启动时请求一次,以后除非App更新
或重新安装
,否则不会在每次打开时请求apple-app-site-association
。
三:苹果开发者账号网站配置和项目配置
①在开发者中心配置Associated Domains
苹果开发者官网,去配置开启identifiers
在appid
中找到需要配置app的appid
,copy下来。然后打开Associated Domains
功能 一定配置新的证书文件。
- 选择
Associated Domains
- 点击
Save
- 记得最后要
更新下载
证书,替换原来的证书
②在Xcode开发工具配置Associated Domains
开发者平台配置完成后 ,进入Xcode
的项目中此处点击+ Capability
,添加Associated Domains
在其中的Domains中
填入你想支持的域名,必须以applinks:为前缀
。
配置Domains
,一定是applinks:+配置的域名
例如:
applinks:www.Share.com
举例:如果上传人员给你的访问路径是:
https://www.baidu.com/.well-known/apple-app-site-association
或
https://www.baidu.com/apple-app-site-association
则Domains
中填入如下,配置好后run
起来
applinks:www.baidu.com
注意:
Universal link
的域名和H5页面URL的域名
不可以是同一个,详情请看Universal link同域不能唤起Universal Link
有跨域问题,Universal Link
必须要求跨域,如果不跨域,就不会跳转(iOS 9.2
之后的改动)
假如当前网页的域名是A
,当前网页发起跳转的域名是B
,必须要求B
和A
是不同域名才会触发Universal Link
,如果B
和A
是相同域名,只会继续在当前WebView
里面进行跳转,哪怕你的Universal Link
一切正常,根本不会打开App
Universal Link
请求apple-app-site-association
时机- 当我们的
App
在设备上第一次运行时,如果支持Associated Domains
功能,那么iOS
会自动去GET
定义的Domain
下的apple-app-site-association
文件
③xcode 配置
TARGETS
Info
LSApplicationQueriesSchemes
添加一个元素weixinULAPI
④appdelegate 里面 设置 见小码快运
当点击某个链接,直接可以进我们的app
了,但是我们的目的是要能够获取到用户进来的链接
,根据链接来展示给用户相应的内容。
比如: 我们进来通过点击一个网页
上的按钮进入app
后,想去某个商品的详情页,怎么做?下面,这里就是通过这种方式,判断商品的详情的请求url
然后,截取参数,在跳转到商品详情页的时候传过去。
我们需要在工程里的实现AppDelegate
里对应的方法:
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler {
if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
NSURL *url = userActivity.webpageURL;
if (url是我们希望处理的) {
//进行我们的处理
} else {
[[UIApplication sharedApplication] openURL:url];
}
}
return YES;
}
四:需要去 第三方平台设置 (比如友盟)
然后工程项目里面的配置,友盟UMSocialGlobal
配置
[UMSocialGlobal shareInstance].universalLinkDic = @{
@(UMSocialPlatformType_WechatSession):@"https://shufa.fanglige.com/applink/"
};
更改回调
- (void)setupUSharePlatforms {
/* 设置微信的appKey和appSecret */
[[UMSocialManager defaultManager] setPlaform:UMSocialPlatformType_WechatSession appKey:@"wx59530f055084abb7" appSecret:@"795af367a7b85a868ed75c1c921ca4a2" redirectURL:nil];
/*设置小程序回调app的回调*/
[[UMSocialManager defaultManager] setLauchFromPlatform:(UMSocialPlatformType_WechatSession) completion:^(id userInfoResponse, NSError *error) {
Log(@"setLauchFromPlatform:userInfoResponse:%@", userInfoResponse);
}];
}
其他
- 支持
HTTPS
呀,一定要是符合苹果认证的HTTPS
证书呀。- 系统问题,确保
iOS9.0
以上- 配置文件问题,
apple-app-site-association
文件中配置的path和测试用的通用链接不一致,注意是区分大小写
的。- 域名问题,
Xcode中
配置的域名一不小心写错了。- 前端开发经常面临跨域问题,必须要求跨域,如果不跨域,就不行。只有当前
webview``的URL
域名,与跳转目标URL
域名不一致时,Universal Link
(通用链接)才生效。
四:Universal Link(通用链接)相关验证
1,苹果为了方便开发者,提供了一个网页来验证我们编写的这个apple-app-site-association
是否合法有效,进入验证网址进行验证
注意:手机上必须安装你需要跳转的应用并配置Associated Domains
a) 在Safari输入
Universal Links
,查看是否弹出跳转链接
b) 在iOS原生备忘录上, 输入Universal Links
,点击是否可以跳转app
在iOS设备中的备忘录中输入APP能识别的链接,然后直接点击此链接,就会直接跳转到你的app
了。或是长按,在出现的弹出菜单中第二项是在XXX
中打开,这也代表着成功:
2,或是你将要测试的网址在Safari
中打开,在出现的网页上方下滑,可以看到有在xxxx
应用中打开,出现菜单:
注意:测试。
一般只会在APP
下载完后初次启动才会下载这个文件,所以如果修改了apple-app-site-association
文件,请删除APP
后重新下载。
五:Universal Link
的运行机制原理
当App初次安装
后或者更新版本后的第一次启动
(第二次启动就不会),向工程配置的applinks:
的域名请求apple-app-site-association
配置文件。
App自动的将apple-app-site-association
配置文件向iOS系统配置。
当任何WebView发起UniversalLink
的url的时候,系统遍历注册过的通用链接,如果命中则直接打开App触发Delegate方法
。
如果没命中,WebView
继续跳转加载url
。
以上都是系统默默替你做的,我们要做的就是确保配置的正确性。
六:常见报错与解决方案
在info.plist
中添加URL scheme
为微信开放平台的AppID
。如果不配置的话,微信无法返回App。
问题1:拉起微信后提示“由于应用universal link
校验不通过,无法完成微信分享”
原因:很可能是App
中注册的AppID
同微信开放平台的不一样。
解决:统一AppID
后解决。
WXApi.registerApp(kWeixinSocial.app_key, universalLink: kWeChatULUrl)
问题2:拉起微信后进行授权,然后立刻返回App
,然后再次调起微信。log
中发现类似下面的语句:
wxTest123Test123Test123://resendContextReqByScheme?wechat_auth_context_id=123455678
原因:由于通用链接授权失败,第二次降级为URLScheme
方式启动微信。
解决:在微信公众平台注册的通用链接要带路径,App
的registerApp
的通用链接参数也一定要带路径,保持一致,单纯的域名就会导致二次降级启动。
正确配置后,从微信返回的通用链接形式是:
https://域名/路径/微信平台的AppID
问题3:为毛有的手机成功了,有的手机就不行呢?
- 上面也提到过,因为网络波动有可能会导致部分用户第一次安装时,无法下载
apple-app-site-association
文件,这个只能引导用户删除重装或者在迭代时修改Associated Domains
配置告诉系统重新下载apple-app-site-association
文件。- 另外一种可能是
苹果
抽风导致,笔者今年年初一碰到过一个蛋疼的问题,从中午一直到下午4点发现重复的删除重装,app
也不会请求服务器的apple-app-site-association
文件,过了4点之后就好了。当时因为时间特殊并没有深究到底是什么原因导致。
问题4:服务器换域名了肿么办?
当Associated Domains
添加新的 Domains
的之后,在app
再次启动的时候抓包发现(不需要删除重装),苹果会给新添加的这个Domains
发送一个请求,请求新Domain
下的apple-app-site-association
文件。也就是说Associated Domains
发生改变的话,系统是会知道的,这样就可以在迭代的时候删除旧的域名,添加新的域名了。另外Domains
的配置也可以使用通配符,例如:applinks:*.mywebsite.com
问题5:全都配置好了,项目也能唤起来了,web页面到底该怎么弄呀?
通用链接指向的服务器的页面到底应该是哪个?之前iOS和安卓用的是同一个网页,也就是说从APP内分享出去的网页,可以被苹果用户和安卓用户同时查看,在这里需要由web童鞋使用js判断当前所处的平台以及其系统。如果是安卓用户,则显示安卓相关提示页面。如果是苹果用户,那么分两种:
- 如果是
9.0
以上的系统,相关的在APP内打开
按钮的链接配置的就是我们的Universal Link
(通用链接)了,且该通用链接地址指向的是一个APP
下载引导页面,那么当用户安装了APP
,即可通过通用链接唤醒APP
;如果用户没有安装app
,那么就会跳转到通用链接指向的APP
下载引导页面,达到最大化的客户导流。- 如果是
9.0
以下的系统,则相应的在APP内打开
的按钮就会发一个跳转到我们APP URL Scheme
的重定向,以实现在Safari
中唤醒我们的APP
。
问题6:当使用通用链接唤醒APP之后,手机右上角有一个小按钮?
那个小按钮只有(在iOS10.0
以下才有)是可以引导用户跳转到Safari
中,名字叫bread crumbs button
(面包屑),当然也去不掉;并且当用户点过这个按钮后,再点击Universal Link(通用链接)不会直接打开对应的APP
。
问题7:备忘录和safari中都可以打开app,怎么分享到其他app里面就不行了?
未跨域导致的,如:分享到微信的链接是https://www.mydomain.com/share.html
,然后该网页中的在app内打开
按钮配置的通用链接为https://www.mydomain.com/index.html
。跨域的意思是说,通用链接 和 调用通用链接的网页不要使用同一域名。即如果通用链接域名为www.mydomain.com
,则通用链接所处的网页域名就不能是www.mydomain.com
。
问题8: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。