由于我们的业务越来越重,并且对于数据的要求也越来越高,所以在业务代码中需要嵌入大量的数据上报代码,而且大部分还都是胶水代码。
所以为了提高人效,降低耦合,精简业务代码等目的,终于!我重构了这部分代码。
一、基础框架
- YGTracking,为基础类。主要功能为,初始化第三方SDK,发送事件,封装第三方方法
- YGTrackingEnum,为枚举定义类,主要功能即定义枚举
- YGTrackingBaseModel,为数据定义基础类,所有其他的数据定义model都继承自它。主要功能,即定义上报所需参数,通过外部参数的不同,定义事件名称,格式化数据,区分上报平台(目前我们有Talking和神策两个平台)
二、使用方法
而外部使用方法十分简单,则可以总结为如下:
- 创建model
- model赋值数据(业务所需上报参数)
- 定义上报平台
- 定义上报事件
- 定义上报参数
- 开始上报
例如:
//使用宏初始化model
YGTrackingModel(YGTrackingPlayActionModel)
//给model赋值业务需要的数据
ygTrackingModel.plan = self.plan;
ygTrackingModel.course = self.course;
ygTrackingModel.playTime = self.actualPlayingTime;
ygTrackingModel.actionType = YGTrackingPlayActionTypeFinish;
//发送事件
YGTrackingGo
复制代码
外部调用只需要关心和业务有关的参数即可,其他事情都被封装在model中进行
三、代码实现
YGTracking.h
#import <Foundation/Foundation.h>#import "SensorsAnalyticsSDK.h"
#import <ShareSDK/ShareSDK.h>
#import "YGTrackingEnum.h"
#import "TalkingData.h"#pragma mark - model.h
#import "YGTrackingClickSearchResultModel.h"
#import "YGTrackingShareEndActionModel.h"
#import "YGTrackingEvaluateActionModel.h"
#import "YGTrackingDownloadActionModel.h"
#import "YGTrackingClickGeneralModel.h"
#import "YGTrackingWatchActionModel.h"
#import "YGTrackingShareActionModel.h"
#import "YGTrackingPageGeneralModel.h"
#import "YGTrackingPlayActionModel.h"
#import "YGTrackingShareModel.h"
#import "YGTrackingOldAdModel.h"
#import "YGTrackVideoAdModel.h"
#import "YGTrackingDealModel.h"
#import "YGTrackingBaseModel.h"
#import "YGTrackingPostModel.h"
#import "YGTrackingAdModel.h"/// 初始化model的宏
#define YGTrackingModel(A) A *ygTrackingModel = [[A alloc]init];
/// 发送model事件的宏
#define YGTrackingGo [YGTracking trackModel:ygTrackingModel];@interface YGTracking : NSObject/**初始化上报SDK*/
+ (void)registTrackSDK;/**神策联通webview中的上报*/
+ (BOOL)showUpWebView:(id)webView WithRequest:(NSURLRequest *)request;/**发送model事件*/
+ (void)trackModel:(YGTrackingBaseModel *)model;/**发送普通事件*/
+ (void)trackEvent:(NSString *)event property:(NSDictionary *)property supportPlatform:(YGAdTrackingPlatform)supportPlatform;@end
复制代码
YGTracking.m
#import "YGTracking.h"
#import "NSString+YGAddition.h"@implementation YGTracking
/**初始化上报SDK*/
+ (void)registTrackSDK {// TalkingData[TalkingData backgroundSessionEnabled];[TalkingData sessionStarted:kYGTalkingDataKey withChannelId:@"AppStore"];[TalkingData setLogEnabled:NO];// 神策SDK初始化[SensorsAnalyticsSDK sharedInstanceWithServerURL:kYGSensorsReportURLandDebugMode:SensorsAnalyticsDebugOff];//神策注册公共属性[[SensorsAnalyticsSDK sharedInstance] registerSuperProperties:@{@"PlatformType": @"iOS"}];// 神策 打开自动采集, 并指定追踪哪些 AutoTrack 事件[[SensorsAnalyticsSDK sharedInstance] enableAutoTrack:SensorsAnalyticsEventTypeAppStart];[[SensorsAnalyticsSDK sharedInstance]trackInstallation:@"AppInstall"];//神策 打通H5[[SensorsAnalyticsSDK sharedInstance] enableLog:NO];NSLog(@"神策版本:%@", [[SensorsAnalyticsSDK sharedInstance]libVersion]);
}/**神策联通webview中的上报*/
+ (BOOL)showUpWebView:(id)webView WithRequest:(NSURLRequest *)request {return [[SensorsAnalyticsSDK sharedInstance]showUpWebView:webView WithRequest:request];
}/**发送model事件*/
+ (void)trackModel:(YGTrackingBaseModel *)model {dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{NSString *event = [model enventName];NSDictionary *property = [model trackParam];if (![event formatNull]|| !IS_DICTIONARY(property)) {return;}if ([model supportPlatform] & YGAdTrackingPlatformSensor) {[[SensorsAnalyticsSDK sharedInstance]track:event withProperties:property];}if ([model supportPlatform] & YGAdTrackingPlatformTD) {[TalkingData trackEvent:event label:@"" parameters:property];}});
}/**发送普通事件*/
+ (void)trackEvent:(NSString *)event property:(NSDictionary *)property supportPlatform:(YGAdTrackingPlatform)supportPlatform {if (![event formatNull]|| !IS_DICTIONARY(property)) {return;}dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{if (supportPlatform & YGAdTrackingPlatformSensor) {[[SensorsAnalyticsSDK sharedInstance]track:event withProperties:property];}if (supportPlatform & YGAdTrackingPlatformTD) {[TalkingData trackEvent:event label:@"" parameters:property];}});
}@end
复制代码
YGTrackingBaseModel.h
#import <Foundation/Foundation.h>
@interface YGTrackingBaseModel : NSObject
/**支持上报平台的类型*/
- (YGAdTrackingPlatform)supportPlatform;
/**返回事件名*/
- (NSString *)enventName;
/**返回事件所需参数dic*/
- (NSDictionary *)trackParam;
@end
复制代码
YGTrackingBaseModel.m
#import "YGTrackingBaseModel.h"@implementation YGTrackingBaseModel
/**支持上报平台的类型*/
- (YGAdTrackingPlatform)supportPlatform {return 0;
}
/**返回事件名*/
- (NSString *)enventName {return @"";
}
/**返回事件所需参数dic*/
- (NSDictionary *)trackParam {return nil;
}
@end
复制代码
目前此基类*YGTrackingBaseModel*只是为了实现一些虚函数而存在,函数实现主要在子类中,下面贴一个子类作为例子:
YGTrackingAdModel.h
#import "YGTrackingBaseModel.h"
@interface YGTrackingAdModel : YGTrackingBaseModel
/// 表现类型 YGAdTrackingModelType 弹框/开屏。。。
@property(nonatomic, assign)YGAdTrackingModelType modelType;
/// 行为类型 YGAdTrackingType 点击/展示/关闭
@property(nonatomic, assign)YGAdTrackingType trackingType;
/// 广告位id
@property(nonatomic, copy)NSString *adID;
/// 广告物料类型(跳转到哪里)
@property(nonatomic, assign)YGOpenLinkType adType;
/// 广告来源类型(美数/亿动。。。)
@property(nonatomic, assign)YGAdResourceType adResourceType;
/// 推荐广告所在页面
@property(nonatomic, assign)NSInteger pageID;
/// 到达该页面的训练id/产品id
@property(nonatomic, copy)NSString *referID;
/// 广告位中的广告id
@property(nonatomic, copy)NSString *contentID;
/// 位置
@property(nonatomic, assign)NSInteger index;
@end
复制代码
YGTrackingAdModel.m
#import "YGTrackingAdModel.h"@implementation YGTrackingAdModel
/**支持上报平台的类型*/
- (YGAdTrackingPlatform)supportPlatform {if (self.trackingType == YGAdTrackingTypeClick) {return YGAdTrackingPlatformSensor | YGAdTrackingPlatformTD;}return YGAdTrackingPlatformTD;
}
/**返回事件名*/
- (NSString *)enventName {if (self.modelType == YGAdTrackingTypeRecommend) {if (self.trackingType == YGAdTrackingTypeDisplay) {return @"view_operation_recommend";}if (self.trackingType == YGAdTrackingTypeClick) {return @"click_operation_recommend";}if (self.trackingType == YGAdTrackingTypeClose) {return @"close_operation_recommend";}}if (self.modelType == YGAdTrackingTypeOpenScreen) {if (self.trackingType == YGAdTrackingTypeDisplay) {return @"view_operation_open_screen";}if (self.trackingType == YGAdTrackingTypeClick) {return @"click_operation_open_screen";}}if (self.modelType == YGAdTrackingTypeTips) {if (self.trackingType == YGAdTrackingTypeDisplay) {return @"view_operation_tips";}if (self.trackingType == YGAdTrackingTypeClick) {return @"click_operation_tips";}if (self.trackingType == YGAdTrackingTypeClose) {return @"close_operation_tips";}}if (self.modelType == YGAdTrackingTypeTips) {if (self.trackingType == YGAdTrackingTypeDisplay) {return @"view_operation_banner";}if (self.trackingType == YGAdTrackingTypeClick) {return @"click_operation_banner";}if (self.trackingType == YGAdTrackingTypeClose) {return @"close_operation_banner";}}return @"";
}
/**返回事件所需参数dic*/
- (NSDictionary *)trackParam {NSMutableDictionary *params = [NSMutableDictionary dictionary];[params setValue:self.adID forKey:@"ad_id"];[params setValue:@(self.adType) forKey:@"ad_type"];[params setValue:@(self.adResourceType) forKey:@"ad_resource_type"];[params setValue:@(self.pageID) forKey:@"page_id"];[params setValue:[NSString stringWithFormat:@"%@_%@", @(self.pageID), self.referID] forKey:@"refer_id"];[params setValue:self.contentID forKey:@"contentid"];[params setValue:@(self.index) forKey:@"frame"];return params;
}
@end
复制代码
后续,无论是时间增改字段,还是事件名替换,或者同一源行为增加事件,都直接修改相应的model即可,对业务代码的修改较少,尤其是像课程或者广告的相关事件,本身数据上报model接收的参数就是课程model或者广告自身model,业务代码几乎不需要更改。
并且,无论是增改线程,更换数据上报平台等等操作,都可以集中进行。
相信,后面我们数据上报工作会越来越高效清晰,为我们数据驱动作为业务行为的同时,也大大提升了此部分的开发效率