Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

Writing in the front

This chapter mainly introduces the classification of buried points and analysis of application exit and startup buried points. More content is output in the form of chapter content.

One, buried point classification

At present, the industry mainstream buried point mainly has the following three kinds.

1. Code burying point

After the application integrates the buried SDK, it initializes the buried SDK at startup, and then invokes the methods provided by the buried SDK to trigger an event when it occurs.

1.1 advantages,

  • Can precisely control the location of the burial point
  • You can easily and flexibly customize events and properties
  • Richer business-related data can be collected
  • It can meet the needs of more refined analysis

1.2 and disadvantages

  • The cost of early burial site is relatively high
  • If the analysis requirements or events change, the application buried concurrent version needs to be modified

2, full buried point

All buried point is also called no buried point, the point of no, non-trace buried point, automatic submerged point, do not need to application developers write code or just write a small amount of code, can be automatically collected in advance all or most of the user’s behavior data, then according to the analysis of actual business needs the sifting the required data and analysis.

2.1 Events that can be collected at the full buried point

  • The startup event of the application($AppStart)

· Cold start: An application is started in this state after it has been terminated by the system. · Hot start: An application that has not been terminated by the system but is still running in the background, and is started in this state

  • Application exit event($AppEnd)

· Double-click the Home button to switch to another app. · Click the Home button to put the current application in the background. · Double click the Home button and swipe up to forcibly kill the current application. · The current application crashes causing the application to exit.

  • Page view event($AppViewScreen)

Page view events within an application, for iOS applications, are simply switching between DIFFERENT UIViewControllers.

  • Control click event($AppClick)

Control click events, such as UIButton, UITableView, etc.

  • Application crash event

2.2 advantages,

  • Early buried point cost is relatively low
  • If the analysis requirements or event design changes, there is no need for the application to modify the buried concurrent version
  • It can effectively solve the problem of historical data backtracking

2.3 and disadvantages

  • It is difficult to achieve comprehensive coverage
  • Service related data cannot be automatically collected
  • More detailed analysis data cannot be satisfied
  • Various compatibility performance issues

3. Visualize buried points

Visual burying point is also called circle selection, which refers to burying point through visual way

3.1. There are generally two application scenarios for visualization buried points

  • By default, no burials are made, and then visually specify which controls to bury (specify burials)
  • By default, all controls are buried, and then visually specify which controls are not buried (to exclude burying).

3.2 advantages and disadvantages

The advantages and disadvantages of visual buried points are similar to the advantages and disadvantages of full buried points as a whole.

Two, full buried point

Typically, there are five common states for iOS applications.

  • (1) Not running. Non-running: the application has not been started or terminated by the system.
  • (2)Inactive. Foreground inactive: The application is about to enter the foreground state, but has not currently received any events (other code may be executing). Applications typically enter this state only briefly when transitioning to another state.
  • (3)Active. Foreground active: the application is running in the foreground, receiving events and processing them. This is also the normal mode for an iOS application to be in the foreground.
  • (4)Background. In background state, an application program enters the background and executes code. Most applications enter this state briefly before being suspended.
  • (5)Suspended. Suspended state: the application enters the background but does not execute any code. The system automatically transfers the application to this state and does not notify the application before executing the operation. When suspended, the application remains in memory, but no code is executed. When the system runs out of memory, the system may purge pending applications without notifying them, freeing up as much running resources as possible for foreground applications.

During an application state transition, the system calls back methods that implement the UIApplicationDelegate protocol class (for example, in Demo, Xcode creates the AppDelegate class by default) and sends local notifications. Then send the corresponding notification). The corresponding relationship between callback methods and local notifications is shown in the following figure:

Here I create an SDK utility class (SensorsSDK) to facilitate subsequent integration. Create a newSensorsSDKTool SDK, as shown below:

Basic preset properties

In general, any event triggered by a user carries some basic information, such as operating system type, operating system version number, carrier information, application version number, and manufacturer, which can be automatically collected by the buried SDK. We call these basic event information (attributes) that are automatically collected by the buried SDK by default preset attributes. Currently you can also define additional information that needs to be collected.

We can get these preset properties when the SensorsAnalyticsSDK class is initialized, and then add these preset properties to each event when it fires. First, add a NSDictionary

attribute automaticProperties to the sensorsAnalyticssDK. m file to save the preset attributes of the event.

Note: $is the prefix that distinguishes the event identifier defined by the system

Preset properties instructions
$os Operating System Type
$lib The SDK type
$manufacturer Set the manufacturer
$lib_version The SDK version number
$os_version Operating system version
$model Mobile phone models
$app_version Application version number

Pay attention to the point

  • The notification is sent when the notification bar is pulled downUIApplicationWillResignActiveNotificationLocal notification; When you swipe up the notification bar, the system sends itUIApplicationDidBecomeActiveNotificationLocal notifications.
  • When you slide up the control center, the system sendsUIApplicationWillResignActiveNotificationLocal notification; The system sends when the control center is pulled downUIApplicationDidBecomeActiveNotificationLocal notifications.
  • When you double-click the Home button to enter the switch application page, the system sends the messageUIApplicationWillResignActive-NotificationLocal notification; Select the current application and the system will sendUIApplicationDidBecome- ActiveNotificationLocal notifications.

Enter the application and exit the application burying point

Example code is as follows:

#import <UIKit/UIKit.h> NS_ASSUME_NONNULL_BEGIN @interface SensorsAnalyticsSDK : @return Return singleton */ + (SensorsAnalyticsSDK *)sharedInstance; @end@interface SensorsAnalyticsSDK (Track) /** @abstract calls the Track interface, and the event @Discussion Properties is an NSDictionary. Where key is the name of the attribute and must be of type NSString; @param eventName eventName @param properties event properties */ - (void)track:(NSString *)eventName properties:(nullable NSDictionary<NSString *, id> *)properties; @endCopy the code
#import "sensorsAnalyticssdk. h" #import <sys/sysctl.h> //SDK system version static NSString *const SensorsAnalyticsVersion = @ "1.0.0"; @interface SensorsAnalyticsSDK () @property (nonatomic, strong) NSDictionary<NSString * id> *automaticProperties; / / / mark whether the application has been received UIApplicationWillResignActiveNotification local notifications @ property (nonatomic, assign) BOOL applicationWillResignActive; @property (nonatomic, getter= islaunchedall carts) BOOL launchedall carts; @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]; / / set to start is a passive tag _launchedPassively = UIApplication. SharedApplication. BackgroundTimeRemaining! = UIApplicationBackgroundFetchIntervalNever; // Add application listener [self setupListeners]; } return self; } #pragma mark- Properties -(NSDictionary<NSString *,id> *)collectAutomaticProperties { NSMutableDictionary *properties = [NSMutableDictionary dictionary]; ["$OS"] = @"iOS"; //SDK type properties[@"$lib"] = @"iOS"; // Set manufacturer properties[@"$manufacturer"] = @"Apple"; //SDK version number properties[@"$lib_version"] = SensorsAnalyticsVersion; / / operating system version number properties. [@ $os_version "] = UIDevice currentDevice. SystemVersion; [@"$model"] = [self deviceModel]; / / the application version number properties [@ $app_version "] = NSBundle. MainBundle. InfoDictionary [@ "CFBundleShortVersionString"]; return [properties copy]; } // Get the phone model -(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 - listener -(void)setupListeners {NSNotificationCenter * Center = [NSNotificationCenter defaultCenter]; / / to monitor App into the background [center addObserver: self selector: @ the selector (applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil]; / / to monitor App into the front desk and active [center addObserver: self selector: @ the selector (applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil]; / / to monitor UIApplicationWillResignActiveNotification local notice [center addObserver: self selector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil]; / / register to monitor UIApplicationDidFinishLaunchingNotification local notice [center addObserver: self selector:@selector(applicationDidFinishLaunching:) name:UIApplicationDidFinishLaunchingNotification object:nil]; } - (void) applicationDidEnterBackground: (NSNotification *) notification {NSLog (@ "App in background"); / / reduction flag bit self. ApplicationWillResignActive = NO; // Trigger $AppEnd [self track:@"$AppEnd" properties:nil]; } - (void) applicationDidBecomeActive: (NSNotification *) notification {NSLog (@ "App into the front desk"); / / reductive mark the if (self. ApplicationWillResignActive) {self. ApplicationWillResignActive = NO; return; } // Set the launcher marker to NO. Self. launchedcarts = NO; // Trigger $AppStart [self track:@"$AppStart" properties:nil]; } - (void) applicationWillResignActive: (NSNotification *) notification {NSLog (@ "App is about to enter the front desk"); self.applicationWillResignActive = YES; } - (void) applicationDidFinishLaunching: (NSNotification *) notification {NSLog (@ "App start"); // If (self. islaunchedall carts) {[self track:@"$appstartAll carts "properties:nil]; } } @end @implementation SensorsAnalyticsSDK (Track) - (void)track:(NSString *)eventName properties:(NSDictionary<NSString *,id> *)properties { NSMutableDictionary *event = [NSMutableDictionary dictionary]; EventName [@"event"] = eventName; / / set the timestamp of events milliseconds event [@ "time"] = [NSNumber numberWithLong: NSDate. Date. TimeIntervalSince1970 * 1000]. NSMutableDictionary *eventProperties = [NSMutableDictionary dictionary]; / / add preset properties [eventProperties addEntriesFromDictionary: self. AutomaticProperties]; / / add custom properties [eventProperties addEntriesFromDictionary: properties]; EventProperties [@"$app_state"] = @"background"; } // Set the event attribute event[@"properties"] = eventProperties; [self printEvent:event]; } @endCopy the code