神奇的Cookie互通魔法

有这么一种业务场景,让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之前的系统占有率已经很低了,完全可以试试这种方式,而且这种需求是非常旺盛的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 143,639评论 1 302
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 61,591评论 1 258
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 95,050评论 0 213
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 41,169评论 0 180
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 48,976评论 1 258
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 38,876评论 1 178
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 30,476评论 2 273
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,229评论 0 167
  • 想象着我的养父在大火中拼命挣扎,窒息,最后皮肤化为焦炭。我心中就已经是抑制不住地欢快,这就叫做以其人之道,还治其人...
    爱写小说的胖达阅读 29,095评论 6 234
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 32,579评论 0 213
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,356评论 2 215
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 30,698评论 1 232
  • 白月光回国,霸总把我这个替身辞退。还一脸阴沉的警告我。[不要出现在思思面前, 不然我有一百种方法让你生不如死。]我...
    爱写小说的胖达阅读 24,272评论 0 32
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,168评论 2 214
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 31,605评论 3 210
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,645评论 0 9
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,035评论 0 166
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 33,609评论 2 232
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 33,698评论 2 233

推荐阅读更多精彩内容