iOS 全埋点-应用程序退出和启动(1)

2021-10-12  本文已影响0人  smile_frank

传送门:

一、埋点分类

目前,业界主流的埋点方式主要有如下三 种。

1、代码埋点

应用程序集成埋点SDK后,在启动时初始化埋点SDK,然后在某个事件发生的时候调用埋点SDK提供的方法来触发事件。

1.1、优点

1.2、缺点

2、全埋点

全埋点也叫无埋点、无码埋点、无痕埋点、自动埋点,指无须应用程序开发工程师写代码或者只写少量的代码,即可预先自动收集用户的所有或者绝大部分的行为数据,然后根据实际的业务分析需求从中筛选出所需的数据并进行分析。

2.1、全埋点可以采集的事件

2.2、优点

2.3、 缺点

3、可视化埋点

可视化埋点也叫圈选,是指通过可视化的方式进行埋点

3.1、可视化埋点一般有两种应用场景

3.2、优缺点

可视化埋点的优点和缺点,整体上与全埋点的优点和缺点类似。

二、全埋点

正常情况下,iOS应用程序主要有5种常见的状态。

在应用程序的状态转换过程中,系统会回调 实现UIApplicationDelegate协议类的一些方法(如 在Demo中,Xcode默认创建AppDelegate类),并发送相应的本地通知(系统会先回调相应的方法,待回调方法执行后,再发送相应的通知)。 回调方法和本地通知的对应关系,如下图所示:

这里我创建一个SDK工具类(SensorsSDK),方便后续集成。
新建一个SensorsSDK工具SDK,如下图所示:

基本预置属性

一般情况下,用户触发的任何事件都携带一些最基本的信息,比如操 作系统类型、操作系统版本号、运营商信息、应用程序版本号、生产厂商 等,这些信息都可以由埋点SDK自动采集。我们把这些默认由埋点SDK自 动采集的事件基本信息(属性)称为预置属性。 当前你也可以定义需要采集的其他信息。

我们可以在SensorsAnalyticsSDK类初始化时获取这些预置属性,然后 在触发事件时,将这些预置属性添加到每一个事件中。 首先,在SensorsAnalyticsSDK.m文件中新增一个 NSDictionary<NSString *,**id**>类型的属性automaticProperties,用于保存事件 的预置属性。

说明: $为区分系统定义的事件标识前缀

预置属性 说明
$os 操作系统类型
$lib SDK类型
$manufacturer 设置制造商
$lib_version SDK版本号
$os_version 操作系统版本号
$model 手机型号
$app_version 应用程序版本号

注意点

示例代码如下:

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface SensorsAnalyticsSDK : NSObject

/**
 @abstract 获取SDK实例
 @return返回单例
 */
+ (SensorsAnalyticsSDK *)sharedInstance;
@end

@interface SensorsAnalyticsSDK (Track)
/**
 @abstract 调用Track接口,触发事件
 @discussion properties是一个NSDictionary(字典)。 其中,key是属性的名称,必须是NSString类型;value则是属性的内容
 @param eventName 事件名称
 @param properties 事件属性
 */
- (void)track:(NSString *)eventName properties:(nullable NSDictionary<NSString *, id> *)properties;
@end
#import "SensorsAnalyticsSDK.h"
//获取手机设备型号
#import <sys/sysctl.h>
//SDK系统版本号
static NSString *const SensorsAnalyticsVersion = @"1.0.0";
@interface SensorsAnalyticsSDK ()
/// 由SDK默认自动采集的事件属性即预置属性
@property (nonatomic, strong) NSDictionary<NSString *, id> *automaticProperties;
/// 标记应用程序是否已收到UIApplicationWillResignActiveNotification本地通知
@property (nonatomic, assign) BOOL applicationWillResignActive;
///是否为被动启动(后台应用程序刷新)
@property (nonatomic, getter=isLaunchedPassively) BOOL launchedPassively;
@end


@implementation SensorsAnalyticsSDK
- (void)dealloc
{
    [[NSNotificationCenter defaultCenter]removeObserver:self];
}
+ (SensorsAnalyticsSDK *)sharedInstance {
    static SensorsAnalyticsSDK *sdk = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sdk = [[SensorsAnalyticsSDK alloc] init];
    });
    return sdk;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        _automaticProperties = [self collectAutomaticProperties];     
        //设置是否位被动启动标记
        _launchedPassively = UIApplication.sharedApplication.backgroundTimeRemaining != UIApplicationBackgroundFetchIntervalNever;  
        //添加应用程序监听
        [self setupListeners];
    }
    return self;
}

#pragma mark- Properties
-(NSDictionary<NSString *,id> *)collectAutomaticProperties {  
    NSMutableDictionary *properties = [NSMutableDictionary dictionary];
    //操作系统
    properties[@"$os"] = @"iOS";
    //SDK类型
    properties[@"$lib"] = @"iOS";
    //设置制造商
    properties[@"$manufacturer"] = @"Apple";
    //SDK版本号
    properties[@"$lib_version"] = SensorsAnalyticsVersion;
    //操作系统版本号
    properties[@"$os_version"] = UIDevice.currentDevice.systemVersion;
    //手机型号
    properties[@"$model"] = [self deviceModel];
    //应用程序版本号
    properties[@"$app_version"] = NSBundle.mainBundle.infoDictionary[@"CFBundleShortVersionString"]; 
    return [properties copy];
}

//获取手机的型号
-(NSString *) deviceModel {
    size_t size;
    sysctlbyname("hw.machine", NULL, &size, NULL, 0);
    char answer[size];
    sysctlbyname("hw.machine", answer, &size, NULL, 0);
    NSString *results = @(answer);
    return results;
}


-(void)printEvent:(NSDictionary *)event {
#if DEBUG
    NSError *error = nil;
    NSData *data = [NSJSONSerialization dataWithJSONObject:event options:NSJSONWritingSortedKeys error:&error];
    if (error) {
        return NSLog(@"Json Serialzed error:%@",error);
    }
    NSString *json = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"[event]:%@",json);
#endif
    
}

#pragma mark - 监听
-(void)setupListeners {   
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
   
   //监听App进入后台
    [center addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
   
   //监听App进入前台并处于活跃状态
    [center addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
    
    //监听UIApplicationWillResignActiveNotification本地通知
    [center addObserver:self selector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];
    
    //注册监听UIApplicationDidFinishLaunchingNotification本地通知
    [center addObserver:self selector:@selector(applicationDidFinishLaunching:) name:UIApplicationDidFinishLaunchingNotification object:nil];
}

-(void)applicationDidEnterBackground:(NSNotification *)notification {
    NSLog(@"App进入后台");
    //还原标记位
    self.applicationWillResignActive = NO;
    //触发$AppEnd事件
    [self track:@"$AppEnd" properties:nil];
}

-(void)applicationDidBecomeActive:(NSNotification *)notification {
    NSLog(@"App进入前台");
    //还原标记位
    if (self.applicationWillResignActive) {
        self.applicationWillResignActive = NO;
        return;
    } 
    //将启动标记设为NO.正常记录事件
    self.launchedPassively = NO; 
    //触发$AppStart事件
    [self track:@"$AppStart" properties:nil];
}

-(void)applicationWillResignActive:(NSNotification *)notification {
    
    NSLog(@"App即将进入前台");
    self.applicationWillResignActive = YES;
}

-(void)applicationDidFinishLaunching:(NSNotification *)notification {
    
    NSLog(@"App启动啦");
    //当应用程序后台运行时,触发被动启动事件
    if (self.isLaunchedPassively) {
        [self track:@"$AppStartPassively" properties:nil];
    }
}

@end


@implementation SensorsAnalyticsSDK (Track)

- (void)track:(NSString *)eventName properties:(NSDictionary<NSString *,id> *)properties {
    NSMutableDictionary *event = [NSMutableDictionary dictionary];
    // 设置事件名称
    event[@"event"] = eventName;
    // 设置事件发生的时间戳,单位为毫秒
    event[@"time"] = [NSNumber numberWithLong:NSDate.date.timeIntervalSince1970 * 1000];
    NSMutableDictionary *eventProperties = [NSMutableDictionary dictionary];
    // 添加预置属性
    [eventProperties addEntriesFromDictionary:self.automaticProperties];
    // 添加自定义属性
    [eventProperties addEntriesFromDictionary:properties];
    //判断是否位被动启动状态
    if(self.isLaunchedPassively) {
        //添加应用程序状态属性
        eventProperties[@"$app_state"] = @"background";
    }
     
    // 设置事件属性
    event[@"properties"] = eventProperties;
   
    [self printEvent:event];
}

@end

上一篇下一篇

猜你喜欢

热点阅读