iOS-deeplink深入探索

1.技术产生的背景?

明确的需求就是:手机打开我们的网站,点击打开按钮或者收藏按钮,用户如果已经安装app,跳转到app做相应的操作。如果没有安装app,则跳转到应用商店提示用户下载安装;或者 app跨域访问app外部的浏览器的数据的方案,包括外部safari,或者QQ,微信,百度等外部app内的浏览器。

  • 设备指纹唯一识别方案(时间、IP、设备类型、操作系统版本,例如友盟SDK,缺点:存在误伤)
  • iOSSafariCookie互通方案(这种方案借助的是iOS9系统新出的一个系统APISFSafariViewController ,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.
    • 7.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。使用*配置,则整个网站都可以使用

苹果验证通用链接是否可用的网站:https://search.developer.apple.com/appsearch-validation-tool/

  • 2.app id 配置
    app IDs 配置,进入开发者网站,找到你自己的bundleId,可以点击edit按钮,开启associate domains,如下图
app id.png
  • 3.项目配置,在项目的Capablities中开启Associated domains,如下图:


    ![image.png](https://upload-images.jianshu.io/upload_images/1653926-a0c1f61d11be0de9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) .png
6.配置时需注意哪些点?
image.png
  • 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.待解决问题
  • wap 端如何判断一个app 是否安装
  • 如何跳转到app store或者安装的app上
9. 参考文档?

SupportUniversalLinks
deepLink iOS 应用到自己APP 记录
iOS9 Universal Links踩坑之旅,移动应用之deeplink唤醒app
简单的Mac-Custom-URL-Scheme-demo
deeplink的一点简单研究

你可能感兴趣的:(iOS-deeplink深入探索)