有这么一种业务场景,让PD们很头痛。PD们绞尽乳汁想尽一切办法去引流用户下载本身设计的App,可是却没法统计真正用户的下载量,这样就没法得出准确的转化率。有没有办法,能统计用户经过引导页而且下载完app的真实体量呢?其实在iOS 9以后是能够作到的。javascript
用户经过浏览器打开一个H5页面,而后经过此H5页面打开App Store下载连接。这中间涉及到一个黑盒即App Store下载过程是不可见的,开发者彻底感知不到。那么咱们想一想有没有一种方式,能取巧的破解这个难题。html
首先从浏览器开始分析,浏览器即WebView。这里会有两种状况:java
实际上,虽然不少用户会在应用内的Webview(下面简称WV)打开引导页,可是真正的场景下,例如在流量巨头微信里头,并不会机会给你引流到App Store,会将你拦截而且忽视请求(Deep Link是另外一个玩意,这里不作讨论)。浏览器
OK,因此咱们反观不少引导用户下载的引导页,一般会检测WV的User-Agent,若是判断不是Safari,一般会引导用户到Safari打开这个连接。至此,其实对于需求来讲,咱们能够先排除应用内的WV,事实上排除这个对接下来的分析颇有益处。缓存
有了具体的使用场景后,咱们就能够分析,而且选出可行性的技术路线了。咱们思考一下,其实归根结到,也就是如何将Safari访问过引导页的数据让开发者感知到,而后传输给后台就完成了。微信
iOS独有的沙盒机制,致使若是想直接从Safari传输数据给App,是不可能的,更况且咱们的App根本没下载完。若是是在引导页点击下载完,而后下载完App再跳回H5,接下来在H5再打开App确实是能够知足统计的。可是这么麻烦的步骤,有几个用户会遵循,而且不以为用户体验实在是太low了吗?cookie
OK,回到根本,咱们想在用户毫无感知的状况下,仅仅经过引导页打开App Store,而且确认下载动做。app
把思路转向Cookie,说到这里,每一个应用内的WV之间的Cookie是独立的,不能共享,而且和Safari的Cookie也是独立的。ui
这里思路卡住了,可是iOS 9有一个新东西:SFSafariViewController,它能够在App内用外部的Safari打开H5,而且与外部Safari共享缓存、Cookie等等。可是它却不能像应用内WV同样取得Cookie等,由于它没有Api给你取。atom
好了,咱们已经找到一条路径,能让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以前的系统占有率已经很低了,彻底能够试试这种方式,并且这种需求是很是旺盛的。