iOSer做为移动开发者中的一员,不得不说深度连接在当下这个“流量”时代已经成为咱们的必修课了,那么什么是深度连接呢?简单的说就是,能够经过一个简单的“连接”,打开App并直接进入该App中的内容页。前提是该手机上已安装该App,且该App须要支持深度连接。例如:在Safari里看到的澎湃新闻App的某一篇新闻 “中国又一新的世界遗产...” 点击下面滚动Banner上的“打开App”按钮即可直接进入澎湃新闻App(已安装)中对应的新闻页面:html
可见在移动端采用深度连接技术,极大的省去了用户打开App、再搜索内容或者点击某处进入指定页面等繁琐的操做,直接点击网页上的打开按钮便可一键到达App内的指定页面。web
在介绍深度连接是怎么来的以前,有一个基础概念须要和你们同步一下:json
SandBox(沙盒)是苹果官方规定的iOS系统强制应用程序只可以读取应用程序内部数据,不能够访问其余应用信息数据的一种机制。后端
SandBox(沙盒)是安全体系中的一种机制,从而苹果公司在设计iOS系统时,考虑到应用之间的信息安全,对应用程序的访问权限设置了限制。api
使用沙盒机制后App之间不能相互访问进行通讯,从而使得App成为一个个的信息孤岛。(弱小可怜又无助)数组
不能说苹果的初衷怎么样,可是带来的问题是显而易见的,那么其实苹果早在2010年 iOS 4 的时候就已经意识到App信息孤立的问题了,因此推出了 URL Scheme 技术,此技术使得iOS系统能够经过特定的URL方式传递参数给另一个App。例如:iOSer://userid=123456&name=sands 。浏览器
不得不认可,这个技术确实解决了当初比较棘手的问题,可是在突飞猛进的今天,URL Scheme的诟病也日渐显著,好比想要实现两个App之间的跳转则须要兼并开发,再好比URL Scheme可以打开App的前提是已经安装了App,若是没有安装则必定会报错,相信下面的错误你们必定都见的很多,更重要的是如今愈来愈多的浏览器已经再也不支持URL Scheme了,这必然让咱们不得不另辟蹊径。安全
相信苹果也是深入的意识到了URL Scheme已经再也不是长久之计了,因此苹果在2015年 iOS 9 中隆重推出了 Universal Links(通用连接) 。bash
Universal Links(通用链接) 一种可以经过点击传统 HTTPS连接 来 启动App 或者 打开对应网站 的技术。服务器
经过惟一的网址, 不须要特别的URI Scheme就能够连接一个特定App里面的视图 。好比:一个App分享内容到微信,用户在微信内置浏览器中看到H5页面内容,而后用户点击触发Universal Links连接后,便可直接打开App内相同的页面内容。(PS: 因为微信 6.5 版本以后作了 屏蔽操做 ,致使没法直接打开App了,但这并不影响系统引导。)
NOTE
Universal links let users open your app when they tap links to your website within WKWebView and UIWebView views and Safari pages, in addition to links that result in a call to openURL:, such as those that occur in Mail, Messages, and other apps.
When a user is browsing your website in Safari and they tap a universal link to a URL in the same domain as the current webpage, iOS respects the user’s most likely intent and opens the link in Safari. If the user taps a universal link to a URL in a different domain, iOS opens the link in your app.
For users who are running versions of iOS earlier than 9.0, tapping a universal link to your website opens the link in Safari.
首先,这是一种标准的HTTPS连接,为何要强调这一点呢?由于它解决了一个很核心的问题,即便你的设备上没有安装App,那么点击该连接也不会出现上面“Safari没法打开该网页,由于网址无效”的报错,它能够看成普通网页正常被访问,为用户体验层面的提高提供了更多的可能。
其次,经过 Universal Links 跳转到本身App从而进行通信的方式不须要两个App之间的兼并开发,别人的App里不须要为打开本身的App作任何配置,只须要本身开发配置好本身的App和网页便可,无论本身的网页是在哪个App里被打开,网页和App之间实现的 Universal Links 都一直有效。
最后,使用这种方式还有几个细节优点点,好比省去了URL Scheme跳转App前的系统确认提示框,相比之下更直接,另外,App未安装时点击以后直接访问网页,一方面解决了URL Scheme在浏览器层面不可知的成功或者失败,同时还可以呈现给用户网页内容,引导用户下载或是进行网页操做,无论从哪一层面来讲,这都是一种完胜URL Scheme的方式。
添加 Universal Links 的支持很简单。你只须要三步便可实现:
apple-app-site-association
文件,文件内容是关于你的App可以处理的URLs的JSON数据apple-app-site-association
文件到你的支持HTTPS的Web服务器。你能够将这个文件放到你服务器的根目录下或者 .well-known
的子文件夹里为了在你的网站和App之间建立一个安全的链接,你创建了它们之间的信任关系。这个信任关系的创建分两步:
apple-app-site-association
文件com.apple.developer.associated-domains
权限(这一部分在下面的 准备处理 Universal Links 的App 中介绍)在您的apple-app-site-association文件中,您能够指定网站中应做为通用连接处理的路径以及不该做为通用连接处理的路径。保持路径列表至关短,并经过正则通配符的方式来匹配更多的路径集。以下是一个 apple-app-site-association
文件的示例,该文件标识了应做为通用连接处理的三个路径。
{
"applinks": { "apps": [], "details": [ { "appID": "9JA89QQLNQ.com.mob.moblink", "paths": [ "/moblink/news/", "/videos/moblink/2019/*"] }, { "appID": "ABCD1234.com.mob.moblink", "paths": [ "*" ] } ] } } 复制代码
注意
不要 在 apple-app-site-association 文件名后面添加 .json 后缀 。
不须要匹配的path则在对应路径前面加 NOT
便可,例如:"paths": [ "/moblink/news/", "NOT /videos/moblink/2010/*", "/videos/moblink/201?/*"]
因为系统会顺序查找路径规则,一旦发现规则相匹配时则中止查找,因此你应该将优先级高的写在优先级低的后面。若是将前面的示例改成: "paths": [ "/moblink/news/", "/videos/moblink/201?/*", "NOT /videos/moblink/2010/*"]
则数组中最后一条规则就没有用了,由于它必定会被前一条规则拦截掉。
在 apple-app-site-association 文件中有不少种方式来指定网站路径。你能够:
*
来指定你的整个网页都支持/moblink/news
来指定部分连接支持*
,例如 /videos/moblink/2017/*
来指定一组连接支持注意
paths数组中的路径字符串是大小写敏感的,必定要注意区分大小写。
建立 apple-app-site-association 文件后,将其上传到HTTPS Web服务器的根目录或 .well-known
子目录。该文件须要经过HTTPS直接访问-无需重定向-位于 https://<domain>/apple-app-site-association
或 https://<domain>/.well-known/apple-app-site-association
。接下来,你须要在你的App中处理 Universal Links。
Universal Links使用了两项技术:第一个是在Web浏览器和App之间启用Handoff的相同机制,第二个是共享Web凭据。关于这两项技术能够参考官方 Web Browser–to–Native App Handoff 和 Shared Web Credentials Reference 。当用户点击一个 Universal Link 时,iOS系统启动你的App,而且带了一个你能够查询到你的App是经过什么方式被启动的 NSUserActivity
对象参数到你的App里。
要在你的App里支持 Universal Links,只须要作以下两步:
AppDelegate
当接收到 NSUserActivity
对象时做出适当的响应在你App的 com.apple.developer.associated-domains 权限里,包含了全部你的App想要看成universal link处理的域名列表。在Xcode的项目主页中,选择 Capabilities
tab页,而后打开 Associated Domains
,以 applinks:
开头添加上你的App支持的域名,例如:applinks:z.t4m.cn
、 applinks:*.ulml.mob.com
注意:这个域名权限列表最多添加20到30个。
配置好Associated Domains以后,就要在 AppDelegate.m
中实现 HandOff
的UIApplicationDelegate
方法以便你的App可以接收到universal link并进行适当的处理。
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler { NSLog(@"title: %@", userActivity.title); // NSUserActivityTypeBrowsingWeb NSLog(@"activityType: %@", userActivity.activityType); // The webpage URL property always contains an HTTP or HTTPS URL, and you can use NSURLComponents APIs to manipulate the components of the URL. NSLog(@"webpageURL: %@", userActivity.webpageURL); // 根据webpageURL的路径、参数等做出适当的处理 // <your code here ...> return YES; } 复制代码
到此,iOS上深度连接的实现就完成了。总体来看,实现iOS上的深度连接涉及到先后端的操做和联调会特别多,尤为是HTTPS证书和错误处理访问到网站那一块,看似简单,但真正一步一步作起来的时候,大大小小的问题仍是很多的,若是对于先后端不是特别熟悉的话可能仍是须要一些时间的。这里我建议你们能够选择第三方深度连接服务,好比MobLink、魔窗、LinkedMe等等,相比之下,MobLink全球领先的移动端场景还原解决方案 以避免费、服务好和功能而出名,较为推荐。
时隔多年,在刚结束没有多久的 WWDC 2019 中,又再一次提到了Universal Links,虽然 整个session不长,也就不到20分钟的时间,但足以体验苹果一直在作这件事儿。
首先,划一下重点:Universal Links 以前只支持在 iOS 和 tvOS 上,如今全面登录到 macOS 上了,不管你是用 UIKit 仍是 AppKit 开发的 Mac App 均可以使用Universal Links。
这一次 WWDC2019 Universal Links 主要的变化有两点:
补充:schemes 上最使人诟病的就是 app 劫持,不少 app 会冒充注册知名大厂的 app scheme 从而拦截调常规的大厂 scheme 唤起,这一点在 Universal Link 就能很好的避免。
上图是 MobLink 这款提供深度连接功能的SDK的apple-app-site-association文件老的写法示例。
这是新的写法,支持了更多更强的配置能力。
在部署网络服务,配置 apple-app-site-association 文件的时候,苹果建议还要遵循一下几点 Tips
必须是正规证书,不能使用自定义证书。
由于在 URL 中会使用不少符号诸如 # ?% ,所以要使用 ASCII 编码。
减小大小有助于在拥堵的网络条件下,更顺畅的生效 Universal Link。若是你的应用面向不通的国家,针对不一样的国家有不一样的配置文件,能够经过国家标记符来分别配置,从而让用户只下载最精简的 JSON 文件。
当 App 安装到设备的时候,会从配置域名上下载这个JSON文件到本地,从而根据配置生效相关的功能。而且设备上下载的这个JSON文件会不按期的更新(亲测过,App 发布版本更新的时候也会准确触发JSON文件的更新)。
网页中的 Smart Banner 与 Universal Links 一块儿配合使用,能够有效的引导未安装 app 的用户前往下载,已安装 app 的用户就能够顺畅的进行跳转
在 XCode 中配置 Universal Links
开发 Universal Links的代码,支持macOS:
// Configuring Your App
func application(_ application: Application, continue userActivity: NSUserActivity, restorationHandler: @escaping ([ UserActivityRestoring]?) -> Void) -> Bool { guard userActivity.activityType == NSUserActivityTypeBrowsingWeb, let url = userActivity.webpageURL, let components = URLComponents(url: url, resolvingAgainstBaseURL: true) else { return false } for queryItem in components.queryItems ?? [] { … return true } 复制代码
在支持 macOS 的状况下,appDelegate 的 Universal Link 的处理也是这个 delegate,区别只是 UIApplication 变为 NSApplication。
因为这个 delegate 会由不少其余的快捷方式触发,不只仅由 Universal Link 触发,因此经过 NSUserActivityTypeBrowsingWeb 来判断来源,剩下的就是标准的 url 处理了。
macOS 下的 Universal Links 工做机制与 iOS 下存在必定的差别
在 mac app 中打开一个 Universal Link
// UIApplication
UIApplication.shared.open(url, options: [ .universalLinksOnly: true ]) { … } // NSWorkspace let configuration = NSWorkspace.OpenConfiguration() configuration.requiresUniversalLinks = true NSWorkspace.shared.open(url, configuration: configuration) { … }复制代码