神奇的Cookie互通魔法

作者: kuailejim | 来源:发表于2017-03-02 11:18 被阅读2881次

    有这么一种业务场景,让PD们很头痛。PD们绞尽乳汁想尽一切办法去引流用户下载自己设计的App,但是却无法统计真正用户的下载量,这样就无法得出准确的转化率。有没有办法,能统计用户通过引导页并且下载完app的真实体量呢?其实在iOS 9之后是可以做到的。

    场景分析

    用户通过浏览器打开一个H5页面,然后通过此H5页面打开App Store下载链接。这中间涉及到一个黑盒即App Store下载过程是不可见的,开发者完全感知不到。那么我们想想有没有一种方式,能取巧的破解这个难题。

    首先从浏览器开始分析,浏览器即WebView。这里会有两种情况:

    • 应用内的UIWebView、WKWebView
    • 应用外的Safari

    实际上,虽然很多用户会在应用内的Webview(下面简称WV)打开引导页,但是真正的场景下,例如在流量巨头微信里头,并不会机会给你引流到App Store,会将你拦截并且忽视请求(Deep Link是另一个玩意,这里不做讨论)。

    OK,所以我们反观很多引导用户下载的引导页,通常会检测WV的User-Agent,如果判断不是Safari,通常会引导用户到Safari打开这个链接。至此,其实对于需求来说,我们可以先排除应用内的WV,事实上排除这个对接下来的分析很有益处。

    技术选型

    有了具体的使用场景后,我们就可以分析,并且选出可行性的技术路线了。我们思考一下,其实归根结到,也就是如何将Safari访问过引导页的数据让开发者感知到,然后传输给后台就完成了。

    iOS独有的沙盒机制,导致如果想直接从Safari传输数据给App,是不可能的,更何况我们的App根本没下载完。如果是在引导页点击下载完,然后下载完App再跳回H5,接下来在H5再打开App确实是可以满足统计的。但是这么麻烦的步骤,有几个用户会遵循,并且不觉得用户体验实在是太low了吗?

    OK,回到根本,我们想在用户毫无感知的情况下,仅仅通过引导页打开App Store,并且确认下载动作。

    把思路转向Cookie,说到这里,每个应用内的WV之间的Cookie是独立的,不能共享,并且和Safari的Cookie也是独立的。

    这里思路卡住了,但是iOS 9有一个新东西:SFSafariViewController,它可以在App内用外部的Safari打开H5,并且与外部Safari共享缓存、Cookie等等。但是它却不能像应用内WV一样取得Cookie等,因为它没有Api给你取。

    好了,我们已经找到一条路径,能让Safari与App共享数据,接下来要解决的就是如何让Safari将数据传到App呢。思考一下,可以用scheme的方式唤起App,然后将参数通过URL带过去。至此,技术过程描述结束。

    实现细节

    流程图

    上面是细节流程图,实现上首先在Safari打开引导页时写入一段Cookie,然后在App下载完成后,打开App时通过SFSafariViewController加载引导页,然后通过window.location.href唤起已经打开的App(注意:如果在已经打开的App再通过这种方式唤起,用户将无感知,而开发者能感知到),这样就能在AppDelegate中拿到传进来的URL了。

    下面我们来看一下代码,首先是一个H5 Demo:

    <html>  
       <head>  
        <script type="text/javascript">
        function getCookie()
        {
            if (document.cookie.length>0)
            { 
            return document.cookie.replace("downloadFlag=", '')
            }
        }
     
        function setCookie()
        {
            var Days = 30;
            var exp = new Date(); 
            exp.setTime(exp.getTime() + Days*24*60*60*1000);
            document.cookie="downloadFlag=true"+";expires="+exp.toGMTString();
        }
    
        function checkCookie()
        {
            downloadFlag=getCookie()
            if (downloadFlag=="true")
            {
                window.location.href = "testCookie://downloadFlag"
            }
            else 
            {
                setCookie()
            }
        }
        </script>
    
        <title>  
           SafariDataToAppDemo
        </title>  
           <meta charset="utf-8">  
       </head>  
       <body onLoad="checkCookie()"> 
    <div>  
        SafariDataToAppDemo
    </div>  
       </body>  
    </html>  
    

    大致解释下这里做了什么,在这个Demo中,在加载的时候判断是否已经存在Cookie,若存在则直接通过window.location.href隐式唤起App,否则写入Cookie。而在Safari中第一次打开,会写入Cookie。

    接下来上native代码:

    #import "ViewController.h"
    #import <SafariServices/SafariServices.h>
    
    @interface ViewController ()
    
    @property (nonatomic, strong) SFSafariViewController *sfVC;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        self.sfVC = [[SFSafariViewController alloc] initWithURL:[NSURL URLWithString:@"http://127.0.0.1/test.html"]];
        [self addChildViewController:self.sfVC];
        [self.sfVC didMoveToParentViewController:self];
        [self.sfVC.view setFrame:CGRectMake(0, 0, 200, 200)];
        [self.view addSubview:self.sfVC.view];
    }
    
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    
    @end
    

    这里就很简单,加载一个小到用户看不见的SFSafariViewController,然后偷偷加载H5 Demo,由于共享Cookie的原因,会读取到有Cookie键值对downloadFlag=true,然后就直接window.location.href隐式唤起App了。然后在AppDelegate上传信息给后台吧!

    PS:这里必须得让SFSafariViewController在当前Window可见,否则iOS将不会加载请求。

    这里还要注意Cookie的失效时间,比如设置10分钟,20分钟(增强准确性,如果设置过长,那很有可能用户通过引导页打开过App Store但是不下载,然后很长一段时间后再下载,也许就是通过另一个渠道下载了)。

    总结

    市面上没有一个埋点平台能做到iOS下载统计,并且iOS 9之前的系统占有率已经很低了,完全可以试试这种方式,而且这种需求是非常旺盛的。

    相关文章

      网友评论

      • 小如99:然而我试了的效果是SFSafariViewController取不到Safari的cookie,通过Safari取不到SFSafariViewController的Cookie,真想不明白你们是怎么获取到的
      • 张xd:“加载一个小到用户看不见的SFSafariViewController,然后偷偷加载H5 Demo” 这样会被苹果拒吗?
      • Vikram_Lee:与我的思路一致
      • RunningDu:无法打开网页
        Safari 打不开该网页,因为网址无效。

        这个提示怎么回事
      • zyg:这里还是有问题 下载后不打开 那是统计不到
        感觉准确不一定很准
      • zerygao:这种方案有点问题吧,不能在Safari打开的时候就写cookie吧。。。如果用户之前已经下载过app了,进入引导页时还写cookie的话,然后再打开app,这样就统计错了吧,这次点击并没有真正的下载。

        另外,cookie失效时间的长短也直接影响了统计结果的正确性,时间值的设置也没有一个标准。所以这种方案虽然能行得通,但在真正使用时问题还是挺大的。
        Henrya:的确,会有这种问题
      • 2a0d699cb83d:很棒。感谢作者
      • IamCRX:还是没搞明白是怎么知道用户下载完应用的?
      • 小怡情ifelse:涨姿势了

      本文标题:神奇的Cookie互通魔法

      本文链接:https://www.haomeiwen.com/subject/qgpxgttx.html