1.技术产生的背景?
简单粗暴,有一个需求:
明确的需求就是:手机打开我们的网站,点击打开按钮或者收藏按钮,用户如果已经安装app,跳转到app做相应的操作。如果没有安装app,则跳转到应用商店提示用户下载安装;或者 app跨域访问app外部的浏览器的数据的方案,包括外部safari,或者QQ,微信,手百等外部app内的浏览器。
* 设备指纹唯一识别方案(时间、IP、设备类型、操作系统版本,例如友盟SDK,缺点:存在误伤)
* iOSSafariCookie互通方案(这种方案借助的是iOS9系统新出的一个系统APISFSafariViewController ,https://github.com/mackuba/SafariAutoLoginTest )
2.主要的应用场景?
Universal Links: Universal Links就是一个通用链接,iOS9以上的用户,可以通过点击这个链接无缝的重定向到一个app应用,而不需要通过safari打开跳转。如果用户没有安装这个app,则会在safari中打开这个链接指向的网页。
Deeper Link: 用户在别的wap网页上,产生了用户行为,用户数据,但是还没下载app,当用户下载app后,打算直接在app内延续之前在wap上的行为和数据的时候,就需要运用到跨越浏览器与app鸿沟的,互通方案。
简单举个例子就是:
用户在微信浏览器里,访问某个页面感兴 趣并且登陆了,然后引导下载了app,等用户下载完app后第一次打开,希望能自动就完成登陆,甚至同步下来一些刚才用户在wap页面上操作的数据
如果能发生跨浏览器与app的互通,除了这个case之外,还可以有更多地自由发挥,设计出更加舒畅的用户体验;这就是 Deeper Link
3.实现的原理?
*当有安装app时:用户先去浏览wap页面,wap页面触发了url跳转,自动唤起了已经安装的app,并且伴随着url传递来了数据,一气呵成,没错用户很自然的从wap上的操作行为,延续到了app上
*当没有安装app时:需要跨越沙盒传递数据,deferred deep link(延迟深度链接
1. 用户通过safari浏览wap站,wap站写用户行为数据进入cookie
2. 用户通过引导下载app,运行app
3.第一次运行app,app内静默的打开一个纯透明safari(让用户感觉不出来)
4. 纯透明的safari访问一个专门用来静默取cookie得页面
5.纯透明的safari访问的取cookie的页面,取到了正确的cookie数据,
6.纯透明的safari将数据通过openurl,静默的回传给app
app拿到浏览器数据后,销毁无用的纯透明safari
4.有哪些突出的优势?
* 用户体验好
* 不会出现误伤即匹配出错的问题
5.如何配置来应用此技术?
按照苹果官方文档来说,支持通用链接非常简单哟,只需要三步
*1.创建一个名字叫做apple-app-site-association,包含固定格式的json文件
*2.将这个文件上传到你的服务器,可以将这个文件放到服务器的根目录下,也可以放到.well-known这个子目录下。
*3.配置app,然后在app里面添加代理方法
具体方法:
1.apple-app-site-association文件
{
"applinks": {
"apps": [],
"details": [
{
"appID": "teamID.bundleId”,
"paths": ["/deaplink","/wwdc/news/","*"]
},
{
"appID": "ABCD1234.com.apple.wwdc",
"paths": [ "*" ]
}
]
}
}
* appID 的 格式为 teamID.bundleId形式。
* paths配置,实际上就是限制哪些路径可以唤醒app,哪些路径不能唤醒app。使用*配置,则整个网站都可以使用;使用特定的URL,例如/wwdc/news/来指定某一个特殊的链接;在特定URL后面添加*,例如 /videos/wwdc/2015/*, 来指定网站的某一部分;除了使用*来匹配任意字符,你也可以使用 ?来匹配单个字符,你可以在路径当中结合这两个字符使用,例如 /foo/*/bar/201?/mypage
苹果验证通用链接是否可用的网站:
https://search.developer.apple.com/appsearch-validation-tool/
* app IDs 配置,进入开发者网站,找到你自己的bundleId,可以点击edit按钮,开启associate domains,如下图:
*项目配置,在项目的Capablities中开启Associated domains,如下图:
* apple-app-site-association文件名字必须为apple-app-site-association,不能带后缀名,有的电脑设置的隐藏后缀名,这点需要注意。
* 配置的paths路径,是区分大小写的
* 注意domains可以添加多个,前缀必须为applinks:,applinks:后为你的服务器的域名。
* 快捷验证,在备忘录中输入https://yourdomain.com/apple-app-site-association,长按这个链接,出现下图提示则配置成功。
Alt text
*服务器必须要支持https,而且需要支持TLS1.2协议以上,不过相信苹果强制支持https之后,这个坑就会慢慢填上了。现在还有很多童鞋的服务器使用的免费的证书,或者证书不被苹果信任,然后就会导致无法下载apple-app-site-association。苹果支持的https根证书列表(https://support.apple.com/en-us/HT204132)
*只支持iOS9以上
*使用charles抓包显示,只有初次安装app时才会去请求apple-app-site-association文件,所以测试时有可能因为网络波动导致apple-app-site-association文件获取失败。这种情况,多卸载几次,安装时使用4G。
*验证各种配置的还有一个网站,需要打成ipa包丢上去。
7.处理跳转的核心代码是?
代码接收Universal Links唤醒
-(BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler{
NSLog(@"userActivity : %@",userActivity.webpageURL.description);
return YES;
}
在appdelegate中实现上面这个方法,当使用Universal Links唤醒app时就执行这个方法;接下来就是打开一个透明safari,等待来自网页的openurl跳转。制作透明safari的方法就是new出来后,alpha改为0,直接present。
-(void)VKGetSafariInfo:(VKSafariReturn)rtBlock {
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0) {
if (rtBlock) {
self.rtblock = rtBlock;
SFSafariViewController *safari = [[SFSafariViewController alloc]initWithURL:self.safariUrl];
safari.delegate = self;
safari.modalPresentationStyle = UIModalPresentationOverCurrentContext;
safari.view.alpha = 0.0f;
self.safari = safari;
UIViewController *currentVC = [self getCurrentVC];
self.currentVC = currentVC;
[currentVC presentViewController:safari animated:NO completion:nil];
}
}else
{
if (rtBlock) {
rtBlock(NO,nil);
}
}
}
当透明safari加载完毕后,略微延迟后直接销毁safari,如果在延迟期间,openurl返回则判断,取cookie数据成功,回调成功,如果超时,就判断取cookie数据失败,回调失败。
此处是SFSafariViewController的delegate回调:
-(void)safariViewController:(SFSafariViewController *)controller didCompleteInitialLoad:(BOOL)didLoadSuccessfully{
__weak typeof(self) weakself = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.timeOut * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[weakself.currentVC dismissViewControllerAnimated:NO completion:^{
weakself.safari = nil;
weakself.currentVC = nil;
}];
[weakself VKTimeOut];
});
}
8.参考文档?
https://developer.apple.com/library/content/documentation/General/Conceptual/AppSearch/UniversalLinks.html#//apple_ref/doc/uid/TP40016308-CH12-SW1 【链接】SupportUniversalLinks
http://awhisper.github.io/2016/05/11/iOSBrowserDomainBridge/
http://blog.csdn.net/Keep_Dream/article/details/56842806
http://www.jianshu.com/p/77b530f0c67b
九.
9.1 wap 端如何判断一个app 是否安装
9.2 如何跳转到app store或者安装的app上
总结:
1.判断当前设备是什么系统
2.判读是否可以识别想要跳转app的协议(apps custom url schemes)
3.根据跳转执行时间(启动app需要的时间较长,js中断时间长,如果没安装,js瞬间就执行完毕)
参考文档:
http://www.52jb.net/biancheng/5533.html
http://blog.csdn.net/goldwave01/article/details/65440928