iOS 10 Universal Links(通用连接),从微信网页连接跳转到公司APP之实现流程详解–2016最新版##
曾经的遭遇…如下:
公司业务需求:APP中分享或者发红包连接到微信好友或者朋友圈,微信用户点击链接,微信APP会加载网页,在网页里点击拆红包,跳回APP,实现这种抢红包,发红包的需求....................
然后各种抓狂,这个.....怎么实现......随后就了解到Universal Links(通用链接),这个新事物
1.基本文档
1.苹果官方文档–中文版
2.苹果官方文档–英文版
3.实现条件
1. 有一个注册的域名
2. 通过 SSL 访问域名
3. 支持上传一个 JSON 文件到你的域名
4. 至少 iOS 9 beta 2 版本 ,这很重要, 因为如果是之前的测试版本你需要做额外的操作。
5. 需要真机测试,模拟器不支持通用链接
6. web server 需要支持 https,客户端需要通告 https 访问,并且不支持任何重定向
4.通用连接–原理流程图
##2. 什么是通用连接 ##
- Apple 推出通用链接:一种能够方便的通过传统 HTTP/HTTPS 链接来启动 APP, 使用相同的网址打开网站和 APP。
- 通过唯一的网址, 不需要特别的schema就可以链接一个特定的视图到APP 里面 。比如:在微信加载的网页中使用了通用链接, 那么用户在Safari、UIWebView或者 WKWebView点击一个链接, iOS设备上的微信app怎会在微信加载的网页里面自动打开公司的APP, 如果没有公司的APP,用户没有安装,则在Safrai中打开响应链接。
- 现在微信APP,已经对外封杀了使用schema自定义协议头的方式来打开第三方公司APP的接口,除非第三方公司是微信的合作伙伴,进行合作提供接口来实现
3.实现通用连接的前提
iOS移动端:
-
必须是开发者账号,才能配置域名
-
使用Xcode配置APP域名—以百度为例,首先就是打开工程配置中的Associated Domains打开
在其中的Domains中填入你想支持的域名(这里不是随便填的,是可以支持你需要的Universal Links的域名), 必须以 applinks: 为前缀
例如:
applinks:baidu.com
applinks:www.baidu.com
Xcode 的 capabilities 里 添加你的 APP 域名, 必须用 applinks: 前置它:还添加一些你可能拥有的子域和扩展(www.domain.com, news.domain.com 等等)。
苹果将会在合适的时候(用户安装公司APP的时候),从这里填入的域名请求文件apple-app-site-association
注意:当你打开Associated Domains后,xcode会在你的工程中添加.entitlements文件
这个列表限制不超过20到30域名
注意* .mywebsite.com不匹配的条目 .mywebsite.com,因为星号后的period.为了匹配.mywebsite.com和mywebsite.com,您需要分别提供单独的applinks条目
并且如果你登陆你的开发者中心,可以看到
这些都是有助于你排除问题的.
到此,你的app就已经可以支持Universal Links(通用链接)了!!!
3.apple-app-site-association文件–JSON格式的
该文件必须存在且为了安全原因可使用 SSL 通过 GET 请求访问到。你可以打开一个文本编辑器然后写一个这样的简单 JSON 格式:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "9JA89QQLNQ.com.apple.wwdc",
"paths": [ "/wwdc/news/", "/videos/wwdc/2015/*"]
},
{
"appID": "ABCD1234.com.apple.wwdc",
"paths": [ "*" ]
}
]
}
}
apple-app-site-association内容解析:
3.1. apple-app-site-association文件名,不要带.json后缀,有些人的电脑是隐藏文件后缀的,这要格外注意
3.2. “app links”–applinks:baidu.com对应添加的域名标识
3.3. “apps”–必须存在,它的值必须是一个空数组
3.4. “details”–是一个包含数个字典的数组,一个应用程序对应一个字典(你的网站所支持的跳转)。数组中的字典的顺序决定了系统寻找对应跳转的匹配顺序,所以您可以指定一个应用程序来处理一个特定的网站的一部分。
3.5. “appID”–两部分组成.第一部分:9JA89QQLNQ是Team ID,第二部分:com.apple.wwdc是Boundle ID
3.6. “paths”–
3.6.1 一个字符串数组,指定你的网站的哪些部分支持跳转到应用程序和哪些网站的部分不想跳转到应用。指定一个域名,不应该作为一个通用的链接处理,在域名paths字符路径的前部添加“NOT”
"paths": [ "/wwdc/news/", "NOT /videos/wwdc/2010/*", "/videos/wwdc/201?/*"]
3.6.2 系统通过paths数组里的路径顺序来评估每个路径的顺序,所以你应该指定路径的高低优先级。注意,只有路径的URL的部分用于比较。其他部分,如查询字符串或片段标识符,都将将被忽略。
3.6.3 多种方法来指定网站apple-app-site-association文件中的路径
1. 使用*指定您的整个网站
2. 包括特定的URL,比如/wwdc/news/,指定一个特定的链接
3. 添加*到特定的URL,比如/videos/wwdc/2015/*,匹配你的网站的指定部分
4. 根据 paths 键设定一个你的app支持的路径列表,只有这些指定的路径的链接,才能被app所处理,举个例子:如果你的网站是www.yohunl.com,你的path写的是”/support/*”,那么当用户点击www.yohunl.com/support/myDoucument,就可以进入你的app了,相反www.yohunl.com/other 就不会.
请注意
你使用的字符串来指定网站路径的路径数组是大小写敏感的。
4.在您创建apple-app-site-association文件后,上传到你的HTTPS web服务器跟目录或者.well-known的子目录。
文件需要通过HTTPS访问且没有任何重定向-
https:// / apple-app-site-association或
https:// / .well-known / apple-app-site-association。
接下来,您需要在你的应用程序处理通用链接.
4.准备APP来处理通用连接
当用户第一次安装 APP时,它会从 https://domain.com/apple-app-site-association 下载这个文件。
在 AppDelegate 里支持通用链接
实现:
//OC版
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler
当 userActivity 是 NSUserActivityTypeBrowsingWeb 类型, 则意味着它已经由通用链接 API 代理。这样的话, 它保证用户打开的 URL 将有一个非空的 webpageURL 属性
webpage的URL属性总是包含一个HTTP或HTTPS URL,并且可以使用NSURLComponents api来操纵这部分URL。
////swift版
import UIKit
extension AppDelegate {
func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool {
if userActivity.activityType == NSUserActivityTypeBrowsingWeb {
let webpageURL = userActivity.webpageURL! // Always exists
if !handleUniversalLink(URL: webpageURL) {
UIApplication.sharedApplication().openURL(webpageURL)
}
}
return true
}
private func handleUniversalLink(URL url: NSURL) -> Bool {
if let components = NSURLComponents(URL: url, resolvingAgainstBaseURL: true), let host = components.host, let pathComponents = components.path?.pathComponents {
switch host {
case "domain.com":
if pathComponents.count >= 4 {
switch (pathComponents[0], pathComponents[1], pathComponents[2], pathComponents[3]) {
case ("/", "path", "to", let something):
if validateSomething(something) {
presentSomethingViewController(something)
return true
}
default:
return false
}
}
default:
return false
}
}
return false
}
}
如果提供的 userActivity 是 NSUserActivityTypeBrowsingWeb 类型, 那么意味着它已经由通用链接 API 代理。这样的话, 它保证用户打开的 URL 将有一个非空的 webpageURL 属性。
为了确保你的 APP 可以翻译 URL 成实际的内容, 你需要做下面几步:
1. 使用 [NSURLComponents]简单解析 webpageURL 到 host(如domain。com), 路径组成同理(如["/"]、"path"、"to"及"thezoo")。
2.确保能识别 host。
3.尝试将 pathComponents 匹配到 APP 的已知内容里。
4.验证该内容实际上可以被呈现。
5.呈现内容给用户。
6.如果上述步骤有任何一个失败, Apple 建议你的 APP 应该在 Safari 上打开 webpageURL 以显示错误。
5.注意
- 如果你实例化一个SFSafariViewController、WKWebView或UIWebView对象处理通用链接,iOS在Safari打开你的网站,而不是打开你的应用。但是,如果用户点击的通用链接是嵌入在SFSafariViewController WKWebView,或UIWebView对象中,iOS系统会打开你的应用。
- 如果你的应用程序使用openURL:打开一个通用链接到你的网站,通用连接总是你尝试在Safari中打开网页链接,而不是去唤醒你的APP实现跳转,iOS系统识别到调用源自你的应用,因此不应该作为一个通用的链接处理。对这个过程的理解是很重要的.(感觉就是如果是加载普通的网页链接,就不要用通用连接处理)
- 如果你从一个活动对象接收到一个无效的URL,友好的失败提示是很重要的。处理一个不受支持的URL,你可以叫openURL:共享应用程序对象在Safari中打开链接。如果你不能使这个调用,向用户显示一条错误消息,解释出错原因。
- 为了保护用户的隐私和安全,不应该使用HTTP当你需要传输数据;相反,使用一个安全的传输协议,比如HTTPS。
- WebServer需要支持https,且https使用有效的证书(是私密链接)。
- 应用会在在刚安装(不是打开)的时候会去applink中的地址下载apple-app-site-association文件,所以如果需要测试,请保证网络通畅;
6.测试
-
需要测试该功能的时候,只需要在记事本或短信中输入App能识别的链接,然后直接点击或是长按就可以了,直接点的效果是跳转到你的App,然后右上角是“去网页”的箭头,长按的效果是弹出的菜单中第二项是“在’XXX’中打开”,这也代表着成功。直接在Safari中输入链接是无效的,必须从一处跳入才可以(比如上一级网页)
-
苹果有个网址(Universal Links测试官网链接)可以检测你的apple-app-site-association是否是有效的,准备好了可以测试一下。
-
验证效果
-
在iOS设备中的备忘录中添加记事本或短信中输入App能识别的链接,然后直接点击此链接,就会直接跳转到你的app了
或是长按,在出现的弹出菜单中第二项是“在’XXX’中打开”,这也代表着成功。
或是你将要测试的网址放到safari中一个网页中,然后点击链接,在出现的网页上方,下滑,可以看到有 在”XX”应用中打开 (很多教程上说,在safari中直接点击,就会跳转到app,但是经过我实际验证,是不可以的,可能是苹果又调整了一下策略吧)
7.前端处理
8.后台服务器
1.提供域名,且必须具有访问服务器根目录的权限,需要上传apple-app-site-association文件
2.服务器支持HTTPS请求,这就需要HTTPS证书