As our business is getting heavier and more demanding on data, we need to embed a lot of data reporting code in our business code, and most of it is glue code.

So in order to improve human efficiency, reduce coupling, streamline business code, and so on, finally! I refactored this part of the code.

1. Basic framework

  • YGTracking, for the base class. The main functions are to initialize third-party SDKS, send events, and encapsulate third-party methods
  • YGTrackingEnum defines classes for enumerations. Its main function is to define enumerations
  • YGTrackingBaseModel, which defines the base class for the data from which all other data definition models inherit. The main function is to define parameters required for reporting, define event names, format data and distinguish reporting platforms (currently we have Talking and Shence platforms) based on different external parameters.

Two, use method

The external use method is very simple, which can be summarized as follows:

  1. Create a model
  2. Model Assigned data (required service reporting parameters)
    1. Defining the Reporting Platform
    2. Defining reported Events
    3. Defining report Parameters
  3. To report to

Such as:

/ / initialization using macro model YGTrackingModel (YGTrackingPlayActionModel) / / to business needs data model assignment YGTrackingModel. Plan = self. The plan; ygTrackingModel.course = self.course; ygTrackingModel.playTime = self.actualPlayingTime; ygTrackingModel.actionType = YGTrackingPlayActionTypeFinish; // Send event YGTrackingGoCopy the code

External calls only care about business-relevant parameters; everything else is encapsulated in the Model

Three, code implementation

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"// initialize the model macro#define YGTrackingModel(A) A *ygTrackingModel = [[A alloc]init];/// send macros for model events#define YGTrackingGo [YGTracking trackModel:ygTrackingModel];@interface YGTracking: NSObject /** Initialization report SDK */ + (void)registTrackSDK; */ + (BOOL)showUpWebView:(id) webview WithRequest:(NSURLRequest *)request; / / + (void)trackModel:(YGTrackingBaseModel *)model; /** sends normal events */ + (void)trackEvent:(NSString *)event property:(NSDictionary *)property supportPlatform:(YGAdTrackingPlatform)supportPlatform; @endCopy the code

YGTracking.m

#import "YGTracking.h"
#import "NSString+YGAddition.h"// TalkingData [TalkingData]; // TalkingData [TalkingData backgroundSessionEnabled]; [TalkingData sessionStarted:kYGTalkingDataKey withChannelId:@"AppStore"];
    [TalkingData setLogEnabled:NO]; God / / ce SDK initialization [SensorsAnalyticsSDK sharedInstanceWithServerURL: kYGSensorsReportURL andDebugMode: SensorsAnalyticsDebugOff];  [[SensorsAnalyticsSDK sharedInstance] registerSuperProperties:@ {@"PlatformType": @"iOS"}]; [[SensorsAnalyticsSDK sharedInstance]] [SensorsAnalyticsSDK sharedInstance]enableAutoTrack:SensorsAnalyticsEventTypeAppStart];
    [[SensorsAnalyticsSDK sharedInstance]trackInstallation:@"AppInstall"]; [[SensorsAnalyticsSDK sharedInstance]enableLog:NO];
    NSLog(@"Divine Policy version :%@", [[SensorsAnalyticsSDK sharedInstance]libVersion]); } /** webview */ + (BOOL)showUpWebView:(id) webview WithRequest:(NSURLRequest *)request {return[[SensorsAnalyticsSDK sharedInstance]showUpWebView:webView WithRequest:request]; / / + (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]; }}); } /** sends normal events */ + (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]; }}); } @endCopy the code

YGTrackingBaseModel.h

#import <Foundation/Foundation.h>@interface YGTrackingBaseModel: NSObject /** Supported platform type */ - (YGAdTrackingPlatform)supportPlatform; /** Returns the event name */ - (NSString *)enventName; /** return dic */ - (NSDictionary *)trackParam; @endCopy the code

YGTrackingBaseModel.m

#import "YGTrackingBaseModel.h"@implementation YGTrackingBaseModel /** supportPlatform type */ - (YGAdTrackingPlatform)supportPlatform {return0; } /** Return event name */ - (NSString *)enventName {return @""; } /** return dic */ - (NSDictionary *)trackParam {return nil;
}
@end
Copy the code

Currently this base class *YGTrackingBaseModel* Only exists to implement some virtual functions, the implementation of the function is mainly in the subclass, the following subclass as an example:

YGTrackingAdModel.h

#import "YGTrackingBaseModel.h"@interface YGTrackingAdModel: YGTrackingBaseModel /// Display type YGAdTrackingModelType popup/open screen... @property(nonatomic, assign)YGAdTrackingModelType modelType; /// Behavior type YGAdTrackingType Click/show/close @Property (nonatomic, assign)YGAdTrackingType trackingType; Id @property(nonatomic, copy)NSString *adID; @property(nonatomic, assign)YGOpenLinkType adType; /// type of advertising source @property(nonatomic, assign)YGAdResourceType adResourceType; @Property (nonatomic, assign)NSInteger pageID; @property(nonatomic, copy)NSString *referID; @property(nonatomic, copy)NSString *contentID; /// position @property(nonatomic, assign)NSInteger index; @endCopy the code

YGTrackingAdModel.m

#import "YGTrackingAdModel.h"@implementation YGTrackingAdModel /** supportPlatform type */ - (YGAdTrackingPlatform)supportPlatform {if (self.trackingType == YGAdTrackingTypeClick) {
        return YGAdTrackingPlatformSensor | YGAdTrackingPlatformTD;
    }
    returnYGAdTrackingPlatformTD; } /** Return event name */ - (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]; [paramssetValue: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
Copy the code

Later, whether it is time increment field, event name replacement, or event increment event of the same source behavior, the corresponding model can be directly modified. The modification of business code is less, especially for events related to courses or advertisements. The parameters received by the data reported to model are course model or advertisement model. The business code requires very little change.

In addition, whether adding threads, changing data reporting platforms and other operations, can be centralized.

I believe that our data reporting work will become more efficient and clear in the future, which will greatly improve the development efficiency of this part while making data-driven business behavior for us