iOS开发者如何写自己的用户行为统计(仿友盟统计)

       一般应用都会集成用户行为统计,现在比较常用的就是友盟统计,Google Analytics,Flurry,MixPanel,由于工作需要,公司需要有自己的特殊需求,所以就仿照友盟写了一个自己公司的用户行为统计。 统计部分简单demo:https://github.com/niuxianbin/XBUsecActionStatistics

       统计信息量很大,因此需要用的数据库,iOS当然就sqlite。统计的用户行为信息很多 ,比如:用户行为发生的时间,用户是匿名还是登录用户,用户是浏览还是点击,点击的是哪个界面等等很多,当然这些需求是更具公司的需求来的,以下使我们公司统计的用户行为部分参数(参数过多已删减):

 
dateCreate                                    创建时间
userId

用户ID 如果是匿名用户 值是机器码 否则填用户 ID

anonymous匿名用户 true|false
actionType1:浏览 2:点击 3:访问 4:刷新
label1:按钮 2:品牌 3:商品
4:分类 5:主题 6:广告 7:精品分类
dataSource1:pc 2:h5 3:android 4:ios
pageId1:品牌商品列表
2:大图
3:品牌列表
4:发现
5:分类列表
6:分类商品列表
7:左侧分类列表
8:分类品牌
9:主题列表
10:主题商品列表                   
tgtId目标ID
label为1时填0
 label为3时填商品ID
label为2时填品牌ID
 label为4时填分类ID
 label为5时填主题ID
label为6时填广告ID
label为7时填精品分类ID
channel渠道名称
parentPageId上级页面

parentTgtId

上级目标ID
device设备型号
  


这个表对应得字段就是你用SQLite建的表的需要一一对应的字段,每当用户点击某一个对应的位置,就向本地数据库存储相应的一条记录。后台一般会提供一个请求方式为post接口,对应的参数是一个就是以上表中的字段,一般情况下,这个参数是个数组,可以一次发送很多条数据库记录。原理就是这样,应该友盟也是这种套路吧。

     用户行为统计一般在项目中被单独封装成一个独立模块,只提供接口外部使用,我用的是FMDB第三方来实现的,部分源代码代码如下,如需完整demo,请稍后等待~~

1 创建数据库以及表的部分代码,

-(void)CreatDataBaseAndTable{
//1.创建数据库
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:@"UserAction.sqlite"];
//创建数据库的队列(线程安全)
FMDatabaseQueue *dataBaseQ = [FMDatabaseQueue databaseQueueWithPath:path];
self.dataBaseQ = dataBaseQ;
[dataBaseQ inDatabase:^(FMDatabase *db) {
BOOL success = [db open];
if (success) {
//2.创建表(保留字段20个)
NSString *str = @"CREATE TABLE IF NOT EXISTS t_UserAction(id INTEGER PRIMARY KEY AUTOINCREMENT, dateCreate TEXT NOT NULL, userId TEXT NOT NULL, anonymous integer NOT NULL, actionType integer NOT NULL, label integer NOT NULL, dataSource integer NOT NULL, pageId integer NOT NULL, tgtId integer NOT NULL, parentPageId integer NOT NULL, parentTgtId integer NOT NULL, device TEXT NOT NULL,Reserved0 integer,Reserved1 integer,Reserved2 integer,Reserved3 integer,Reserved4 integer,Reserved5 integer,Reserved6 integer,Reserved7 integer,Reserved8 integer,Reserved9 integer,Reserved10 integer,Reserved11 TEXT)";
if ([db executeUpdate:str]) {
NSLog(@"表创建成功!");
}else{
NSLog(@"创建表失败!");
}
}else{
NSLog(@"数据库创建失败!");
}
}];
}

//创建数据库以及表的部分代码,一般来讲表中字段由于新的需求可能会变更,因此要预留保留字段。

2 遍历数据库信息发送给后台

-(void)SelectAllInfo{
NSString *strSql = @"SELECT * FROM t_UserAction";
NSMutableArray *arr=[NSMutableArray array];
NSMutableArray *TempDataArrM=[NSMutableArray array];
NSMutableArray *TempDataArrM1=[NSMutableArray array];
NSMutableArray *ParamStr=[NSMutableArray array];
//查询语句 执行的方法
[self.dataBaseQ inDatabase:^(FMDatabase *db) {
FMResultSet *set =[db executeQuery:strSql];
while ([set next]) {
//dateCreate
NSString *dateCreate = [set stringForColumn:@"dateCreate"];
//userId
NSString *userId= [set stringForColumn:@"userId"];
//dateCreate
int anonymous = [set boolForColumn:@"anonymous"];
//actionType
int actionType = [set intForColumn:@"actionType"];
//label
int label = [set intForColumn:@"label"];
//dataSource
int dataSource = [set intForColumn:@"dataSource"];
//pageId
int pageId = [set intForColumn:@"pageId"];
//tgtId
long tgtId = [set longForColumn:@"tgtId"];
//parentPageId
int parentPageId = [set intForColumn:@"parentPageId"];
//parentTgtId
long parentTgtId = [set longForColumn:@"parentTgtId"];
//device
NSString *device = [set stringForColumn:@"device"];
[TempDataArrM addObject:dateCreate];
[TempDataArrM1 addObject:dateCreate];

NSString *TempParamStr=[NSString stringWithFormat:@"{\"dateCreate\":\"%@\",\"userId\":\"%@\",\"anonymous\":%d,\"actionType\":%d,\"label\":%d,\"dataSource\":%d,\"pageId\":%d,\"tgtId\":%ld,\"parentPageId\":%d,\"parentTgtId\":%ld,\"device\":\"%@\",\"channel\":\"app_store\"}",dateCreate,userId,anonymous,actionType,label,dataSource,pageId,tgtId,parentPageId,parentTgtId,device];
[arr addObject:TempParamStr];
[ParamStr addObject:TempParamStr];
if (arr.count==100&&[UserActionSwitch isEqualToString:@"ON"]) {

NSString *TotleParam=[arr componentsJoinedByString:@","];
NSString *paramStr=[NSString stringWithFormat:@"{\"datas\":[%@]}",TotleParam];

[[nxbHttpTools sharedNetworkTools]POST:userAPI(@"mm.st.action.push/1.0") parameters:@{@"data":paramStr} success:^(NSURLSessionDataTask * _Nonnull task, id _Nonnull responseObject) {
NSLog(@"大于100条数据:%@",responseObject);
//发送成功后删除记录
if ([responseObject[@"code"] intValue]==200) {
[TempDataArrM enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSString *creadeDate=TempDataArrM[idx];
[self DeleteTheRecord:creadeDate];
NSLog(@"单个删除元素");
}];
[TempDataArrM removeAllObjects];
}
} failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) {
NSLog(@"%@",error);
}];
NSLog(@"%@",arr);
[arr removeAllObjects];
}

}

if (ParamStr.count>1&&ParamStr.count<100&&[UserActionSwitch isEqualToString:@"ON"]) {

NSString *TotleParam=[ParamStr componentsJoinedByString:@","];
NSLog(@"小于100条数据:%@",TotleParam);
NSString *paramStr1=[NSString stringWithFormat:@"{\"datas\":[%@]}",TotleParam];

[[nxbHttpTools sharedNetworkTools]POST:userAPI(@"mm.st.action.push/1.0") parameters:@{@"data":paramStr1} success:^(NSURLSessionDataTask * _Nonnull task, id _Nonnull responseObject) {
NSLog(@"%@",responseObject);
//发送成功后删除记录
if ([responseObject[@"code"] intValue]==200) {
[TempDataArrM1 enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSString *creadeDate=TempDataArrM1[idx];
[self DeleteTheRecord:creadeDate];
}];
[TempDataArrM1 removeAllObjects];
}
} failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) {
NSLog(@"%@",error);
}];
[ParamStr removeAllObjects];

}

}];
}

3 发送成功后将本地数据库对应的一条记录删除

 //删除一条记录
-(void)DeleteTheRecord:(NSString *)dateCreate{
NSString *deleteSql = [NSString stringWithFormat:
@"delete from t_UserAction where dateCreate = '%@'",dateCreate];
[self.dataBaseQ inDatabase:^(FMDatabase *db) {
BOOL res = [db executeUpdate:deleteSql];
if (res) {
NSLog(@"发送完成,删除表中一条数据");
}else{
NSLog(@"发送失败,删除表中一条数据失败!");
}
}];

}
  有其他疑问可以随时问我哦~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值