专栏名称: 程序员大咖
为程序员提供最优质的博文、最精彩的讨论、最实用的开发资源;提供最新最全的编程学习资料:PHP、Objective-C、Java、Swift、C/C++函数库、.NET Framework类库、J2SE API等等。并不定期奉送各种福利。
目录
相关文章推荐
程序员的那些事  ·  3·15 ... ·  2 天前  
程序员的那些事  ·  当初给你定级 P8 ... ·  4 天前  
程序员的那些事  ·  大家有没有发现一个奇特现象:你能在一个公司工 ... ·  3 天前  
码农翻身  ·  满血版DeepSeek,又升级了! ·  3 天前  
51好读  ›  专栏  ›  程序员大咖

Universal Link 前端部署采坑记

程序员大咖  · 公众号  · 程序员  · 2017-09-06 10:24

正文

点击上方“ 程序员大咖 ”,选择“置顶公众号”

关键时刻,第一时间送达!


前言

文章会适当说一些如何开发iOS上的universal link,但类似的文章太多了一艘一大堆,每篇都介绍的挺清楚,因此也不是重点

本文更加会侧重从前端的角度,将整个universal link 部署应用到wap app中的一些策略和一些问题解决办法

其实整个Universal Link没啥难的,真正上线过Universal link的人这些应该都趟过一遍了,本文主要是我们team去应用Universal link的时候一些文档沉淀和记录


Schema VS Universal Link



Deeplink相关的技术,在wap中唤起app其实应用最最广泛的并不是Universal Link,而是直接Schema跳转


location.href = 'schema://xxxx'


并且一般各大APP都会给自己做一套路由体系,这样其实可以直接在schema头后面对接路由体系,做到一行schema定位打开任意App内功能界面(我就不详细扯路由的事了)


- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {

if ([[url absoluteString] hasPrefix:@"schema://"]) {

[[WKDispatcher sharedInstance] operationObjectFromRouteURL:[url absoluteString]];//路由

return YES;

}

}


如果单纯为了实现deeplink -- 在WAP上打开App,并且传递来数据信息,定位App内的具体逻辑,那么Schema就够了,其实没必要上Universal Link,Schema相当于是很特殊的Url,他是schema://xxx这种样子,如果安装了APP才能支撑跳转这种Schema Url,如果没安装APP就没任何效果,而Universal Link则是把普通url,长http://xxx.xxx.xxx/xxx这样的Normal Url,如果安装了App,就能像Schema一样传递给App,延续App内逻辑,如果没装App,则还会继续在浏览器里跳转这个Normal Url



Schema的弊端



Schema无法判断是否安装App


一定会有这样的产品需求的:


  • 如果已经安装App,则打开App

  • 如果没有安装App,则前往下载App


浏览器实际上是没有能力判断手机里是否安装了某个App的,所以聪明的程序员们选择了讨巧的方法


try {

var appSchema = 'schema://xxxx';

if ($.os.ios) {

location.href = openNALocation; //location.href 打开schema

}

else {

$('body').append('

}

}catch (e) {}


//延迟1000秒

setTimeout(function () {

if ($.os.ios) {

location.href = `https://itunes.apple.com/us/app/idxxxxxxx?mt=8`;

}

else {

location.href = `https://xxx.xxx.xxx/xxx/xxx.apk`;//直接apk下载link

}

},1000)


  • 首先发起跳转Schema

如果没安装App,会打开App失败,没效果

如果安装App,会成功打开App

  • 延迟1000ms

如果没安装App,Schema打开失败,等1000秒后会自动跳转

如果安装App,App会打开,当前网页会被暂停,这延迟代码不会执行


聪明的人会发现,这样有个风险,如果用户打开APP成功后,又手动切回浏览器,那么延迟1000ms的代码依然会执行,安卓会跳出下载apk包得提示,iOS会又再度跳到Appstore,但这个瑕疵也不是太大的问题,所以这种做法被普遍采用,运用在各种安装就跳转,不安装就下载的用户场景。



安卓这么用挺好,iOS有个讨厌的弹框



如果用户没有安装App,那么他一定会经历2个事情


  • schema打开app,但是失败

  • 延迟后,跳转下载App


在第一个环节,安卓上schema打开失败,没有任何反映,也没有任何提示,一切顺利,但是iOS就不同了。


schema会弹个可恶的跳转失败的框


1504334347900


然后再延迟后弹跳转AppStore的框


1504334376521



Schema被很多App禁止,比如微信手百



Schema被广泛使用,从浏览器中唤起打开专门的App,但这并不被很多App认可,比如微信,手机百度,他们本身除了浏览网页以外有其他的使用场景,所以站在微信/手百的角度,并不希望用户为了看一些分享和内容就跳出微信/手百的App,于是这些客户端拦截了Schema,使得所有Schema都无法生效。


于是不得已,广大开发者只好针对,微信/手百,等特殊UA信息,展现出蒙层,引导用户用系统/外部浏览器打开




Universal Link 解决 Schema的弊端



开篇就说了,如果你单纯为了能让wap打开App,Schema就能做到了,Universal Link的意义则是把普通url,也赋予了能打开App的能力,而不必编写专门的Schema Url去唤起App


Schema 的2个弊端确实能通过Universal Link解决


不同于Schema,在没装App的时候,Universal Link他也是一个合法的url链接,浏览器可以正常跳转,因此不会出现在iOS上讨人厌的框


Universal Link目前还没有基于iOS的UI/WKWebView的应用进行拦截,所以目前看还是能突破微信/手百的封锁。(以后,不好说啊~)



Universal Link 开发



类似的话题,随便搜搜Universal Link能搜到一大堆,我这里就略微多啰嗦两句,一般各大教程里会反复说的,我尽量一带而过,多说点我遇到的坑



配置apple-app-association



究竟哪些的url会被识别为Universal Link,全看这个apple-app-association文件

Apple Document UniversalLinks.html


  • 你的域名必须支持Https

  • 域名根目录下放这个文件apple-app-association,不带任何后缀

  • 文件为json保存为文本即可

  • json按着官网要求填写即可


怎么写json其实没啥可教的,满世界的文章都教你咋写了,我们看个例子,点下面的链接,你的浏览器就会自动把知乎的apple-app-association的json file给down下来


知乎的 apple-app-association 文件



划重点


有心人可能看到,知乎的Universal Link配置的是 oia.zhihu.com 这个域名,并且对这个域名下比如/answers /questions /people 等urlpath进行了识别,也就是说,知乎的universal link,只有当你访问 https://oia.zhihu.com/questions/xxxx,在移动端会触发Universal Link,而知乎正经的Urlhttps//www.zhihu.com/questions/xxx是不会触发Universal Link的,知乎为什么制作,为什么不把他的主域名配置Universal Link,这是由于Universal Link的一个大坑所致


PS.


apple-app-association 你可以看完全了知乎的json file,会发现里面也不止是 universal link

苹果的一些其他功能都和apple-app-association有关,都需要配置这个文件,增加更多json字段信息

比如Hand off 还有一些跨Web&App的分享


测试是否正确


苹果官方提供了一个网站来测试你配置的域名apple-app-association是否正常work


https://search.developer.apple.com/appsearch-validation-tool/



这个网站有点SB,就是你用他测试不通过,其实Universal Link也可能不生效的,比如我把知乎的oia.zhihu.com输入进去,他就没感应到,认为没有。我搜索的时候,发现也有人发现了这个问题,反正可以当个参考



配置iOS App工程



  • 开发者中心证书打开Associated Domains

  • 工程配置Associated Domains

  • 将你apple-app-association所在域名配置进去

  • 给你的工程像Schema的OpenUrl一样,编写App被唤醒后的处理逻辑



#pragma mark Universal Links

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler {

if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {

NSURL *webUrl = userActivity.webpageURL;

[self handleUniversalLink:webUrl]; // 转化为App路由

}

return YES;

}


恩比较千篇一律,我不多说了



Universal Link的基本运作流程



  • APP第一次启动 or APP更新版本后第一次启动

  • APP向工程里配置的域名发起Get请求拉取apple-app-association Json File

  • APP将apple-app-association注册给系统

  • 由任意webview发起跳转的url,如果命中了apple-app-association注册过的通用链接

  • 打开App,触发Universal Link delegate

  • 没命中,webview继续跳转url


在你进行apple-app-association 以及 App工程的配置之后,整个Universal Link的运作流程完全由系统控制了



Universal Link 采坑



整个Universal Link其实真要只是开发完成,完全写不了几行代码,就差不多搞定了,不过还真是踩了几个坑


跨域



前端开发经常面临跨域问题,恩Universal Link也有跨域问题,但不一样的是,Universal Link,必须要求跨域,如果不跨域,就不行,就失效,就不工作。(iOS 9.2之后的改动,苹果就这么规定这么设计的)


这也是上面拿知乎举例子的时候重点强调的一个问题,知乎为什么使用oia.zhihu.com做Universal Link?


  • 假如当前网页的域名是 A

  • 当前网页发起跳转的域名是 B

  • 必须要求 B 和 A 是不同域名,才会触发Universal Link

  • 如果B 和 A 是相同域名,只会继续在当前WebView里面进行跳转,哪怕你的Universal Link一切正常,根本不会打开App







请到「今天看啥」查看全文