Ta android + ios
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7f8b2a224e9edc24da27dd4ea03a3b39
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// TAAppEndEvent.h
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by Yangxiongon 2022/6/17.
|
||||
//
|
||||
|
||||
#import "TAAutoTrackEvent.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TAAppEndEvent : TAAutoTrackEvent
|
||||
@property (nonatomic, copy) NSString *screenName;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 40a6155cb5c236b4b8087a56f07b6b99
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// TAAppEndEvent.m
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by Yangxiongon 2022/6/17.
|
||||
//
|
||||
|
||||
#import "TAAppEndEvent.h"
|
||||
#import "TDPresetProperties+TDDisProperties.h"
|
||||
|
||||
@implementation TAAppEndEvent
|
||||
|
||||
- (NSMutableDictionary *)jsonObject {
|
||||
NSMutableDictionary *dict = [super jsonObject];
|
||||
|
||||
if (![TDPresetProperties disableScreenName]) {
|
||||
self.properties[@"#screen_name"] = self.screenName ?: @"";
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 70f1894193c33dd49b8c7a95f3483903
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// TAAppStartEvent.h
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by Yangxiongon 2022/6/17.
|
||||
//
|
||||
|
||||
#import "TAAutoTrackEvent.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TAAppStartEvent : TAAutoTrackEvent
|
||||
@property (nonatomic, copy) NSString *startReason;
|
||||
@property (nonatomic, assign) BOOL resumeFromBackground;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 10585deadfd0a0b41b8af66b473a82d1
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// TAAppStartEvent.m
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by Yangxiongon 2022/6/17.
|
||||
//
|
||||
|
||||
#import "TAAppStartEvent.h"
|
||||
#import <CoreGraphics/CoreGraphics.h>
|
||||
#import "TDPresetProperties+TDDisProperties.h"
|
||||
|
||||
@implementation TAAppStartEvent
|
||||
|
||||
- (NSMutableDictionary *)jsonObject {
|
||||
NSMutableDictionary *dict = [super jsonObject];
|
||||
|
||||
if (![TDPresetProperties disableResumeFromBackground]) {
|
||||
self.properties[@"#resume_from_background"] = @(self.resumeFromBackground);
|
||||
}
|
||||
if (![TDPresetProperties disableStartReason]) {
|
||||
self.properties[@"#start_reason"] = self.startReason;
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7dc79746c3bbc9e448ed4c906d915101
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// TAAutoClickEvent.h
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by Yangxiongon 2022/6/15.
|
||||
//
|
||||
|
||||
#import "TAAutoTrackEvent.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TAAutoClickEvent : TAAutoTrackEvent
|
||||
@property (nonatomic, copy) NSString *elementId;
|
||||
@property (nonatomic, copy) NSString *elementContent;
|
||||
@property (nonatomic, copy) NSString *elementType;
|
||||
@property (nonatomic, copy) NSString *elementPosition;
|
||||
@property (nonatomic, copy) NSString *pageTitle;
|
||||
@property (nonatomic, copy) NSString *screenName;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de4bf411c264c504a864d1110c8edb45
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// TAAutoClickEvent.m
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by Yangxiongon 2022/6/15.
|
||||
//
|
||||
|
||||
#import "TAAutoClickEvent.h"
|
||||
#import "TDPresetProperties+TDDisProperties.h"
|
||||
|
||||
@implementation TAAutoClickEvent
|
||||
|
||||
- (NSMutableDictionary *)jsonObject {
|
||||
NSMutableDictionary *dict = [super jsonObject];
|
||||
|
||||
if (![TDPresetProperties disableScreenName]) {
|
||||
self.properties[@"#screen_name"] = self.screenName;
|
||||
}
|
||||
if (![TDPresetProperties disableElementId]) {
|
||||
self.properties[@"#element_id"] = self.elementId;
|
||||
}
|
||||
if (![TDPresetProperties disableElementType]) {
|
||||
self.properties[@"#element_type"] = self.elementType;
|
||||
}
|
||||
if (![TDPresetProperties disableElementContent]) {
|
||||
self.properties[@"#element_content"] = self.elementContent;
|
||||
}
|
||||
if (![TDPresetProperties disableElementPosition]) {
|
||||
self.properties[@"#element_position"] = self.elementPosition;
|
||||
}
|
||||
if (![TDPresetProperties disableTitle]) {
|
||||
self.properties[@"#title"] = self.pageTitle;
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6822b7c6562f6234992a3529f37709f0
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// TAAutoPageViewEvent.h
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by Yangxiongon 2022/6/15.
|
||||
//
|
||||
|
||||
#import "TAAutoTrackEvent.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TAAutoPageViewEvent : TAAutoTrackEvent
|
||||
@property (nonatomic, copy) NSString *pageUrl;
|
||||
@property (nonatomic, copy) NSString *referrer;
|
||||
@property (nonatomic, copy) NSString *pageTitle;
|
||||
@property (nonatomic, copy) NSString *screenName;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3496858b20c04445b91102798553dc1
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// TAAutoPageViewEvent.m
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by Yangxiongon 2022/6/15.
|
||||
//
|
||||
|
||||
#import "TAAutoPageViewEvent.h"
|
||||
#import "TDPresetProperties+TDDisProperties.h"
|
||||
|
||||
@implementation TAAutoPageViewEvent
|
||||
|
||||
- (NSMutableDictionary *)jsonObject {
|
||||
NSMutableDictionary *dict = [super jsonObject];
|
||||
|
||||
if (![TDPresetProperties disableScreenName]) {
|
||||
self.properties[@"#screen_name"] = self.screenName;
|
||||
}
|
||||
if (![TDPresetProperties disableTitle]) {
|
||||
self.properties[@"#title"] = self.pageTitle;
|
||||
}
|
||||
if (![TDPresetProperties disableUrl]) {
|
||||
self.properties[@"#url"] = self.pageUrl;
|
||||
}
|
||||
if (![TDPresetProperties disableReferrer]) {
|
||||
self.properties[@"#referrer"] = self.referrer;
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 80c9b30ac6f8e9f4793c4c456666088f
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// TAAutoTrackEvent.h
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by Yangxiongon 2022/6/15.
|
||||
//
|
||||
|
||||
#import "TATrackEvent.h"
|
||||
#import "TDConstant.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TAAutoTrackEvent : TATrackEvent
|
||||
|
||||
/// It is used to record the dynamic public properties of automatic collection events. The dynamic public properties need to be obtained in the current thread where the event occurs
|
||||
@property (nonatomic, strong) NSDictionary *autoDynamicSuperProperties;
|
||||
|
||||
/// Static public property for logging autocollection events
|
||||
@property (nonatomic, strong) NSDictionary *autoSuperProperties;
|
||||
|
||||
/// Returns the automatic collection type
|
||||
- (ThinkingAnalyticsAutoTrackEventType)autoTrackEventType;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3090a87679ab84a4abee1eec9aad1b89
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// TAAutoTrackEvent.m
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by Yangxiongon 2022/6/15.
|
||||
//
|
||||
|
||||
#import "TAAutoTrackEvent.h"
|
||||
#import "ThinkingAnalyticsSDKPrivate.h"
|
||||
#import "TDPresetProperties+TDDisProperties.h"
|
||||
|
||||
@implementation TAAutoTrackEvent
|
||||
|
||||
- (NSMutableDictionary *)jsonObject {
|
||||
NSMutableDictionary *dict = [super jsonObject];
|
||||
// Reprocess the duration of automatic collection events, mainly app_start, app_end
|
||||
// app_start app_end events are collected by the automatic collection management class. There are the following problems: the automatic collection management class and the timeTracker event duration management class are processed by listening to appLifeCycle notifications, so they are not at a precise and unified time point. There will be small errors that need to be eliminated.
|
||||
// After testing, the error is less than 0.01s.
|
||||
CGFloat minDuration = 0.01;
|
||||
if (![TDPresetProperties disableDuration]) {
|
||||
if (self.foregroundDuration > minDuration) {
|
||||
self.properties[@"#duration"] = @([NSString stringWithFormat:@"%.3f", self.foregroundDuration].floatValue);
|
||||
}
|
||||
}
|
||||
if (![TDPresetProperties disableBackgroundDuration]) {
|
||||
if (self.backgroundDuration > minDuration) {
|
||||
self.properties[@"#background_duration"] = @([NSString stringWithFormat:@"%.3f", self.backgroundDuration].floatValue);
|
||||
}
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
- (ThinkingAnalyticsAutoTrackEventType)autoTrackEventType {
|
||||
if ([self.eventName isEqualToString:TD_APP_START_EVENT]) {
|
||||
return ThinkingAnalyticsEventTypeAppStart;
|
||||
} else if ([self.eventName isEqualToString:TD_APP_START_BACKGROUND_EVENT]) {
|
||||
return ThinkingAnalyticsEventTypeAppStart;
|
||||
} else if ([self.eventName isEqualToString:TD_APP_END_EVENT]) {
|
||||
return ThinkingAnalyticsEventTypeAppEnd;
|
||||
} else if ([self.eventName isEqualToString:TD_APP_VIEW_EVENT]) {
|
||||
return ThinkingAnalyticsEventTypeAppViewScreen;
|
||||
} else if ([self.eventName isEqualToString:TD_APP_CLICK_EVENT]) {
|
||||
return ThinkingAnalyticsEventTypeAppClick;
|
||||
} else if ([self.eventName isEqualToString:TD_APP_CRASH_EVENT]) {
|
||||
return ThinkingAnalyticsEventTypeAppViewCrash;
|
||||
} else if ([self.eventName isEqualToString:TD_APP_INSTALL_EVENT]) {
|
||||
return ThinkingAnalyticsEventTypeAppInstall;
|
||||
} else {
|
||||
return ThinkingAnalyticsEventTypeNone;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)ta_validateKey:(NSString *)key value:(id)value error:(NSError *__autoreleasing _Nullable *)error {
|
||||
[TAPropertyValidator validateAutoTrackEventPropertyKey:key value:value error:error];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b29666e1c445d994991de96212385d20
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// TAPushClickEvent.h
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by liulongbing on 2023/5/31.
|
||||
//
|
||||
#import "TAAutoTrackEvent.h"
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TAPushClickEvent : TAAutoTrackEvent
|
||||
|
||||
@property (nonatomic, strong) NSDictionary *ops;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fec359995ca52d242b7b0857f45a3b4d
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// TAPushClickEvent.m
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by liulongbing on 2023/5/31.
|
||||
//
|
||||
|
||||
#import "TAPushClickEvent.h"
|
||||
|
||||
@implementation TAPushClickEvent
|
||||
|
||||
- (NSMutableDictionary *)jsonObject {
|
||||
NSMutableDictionary *dict = [super jsonObject];
|
||||
self.properties[@"#ops_receipt_properties"] = self.ops;
|
||||
return dict;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d30d06823cd9afb49b3635a39a6adcf5
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// TAAutoTrackProtocol.h
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by Yangxiongon 2022/7/1.
|
||||
//
|
||||
|
||||
#ifndef TAAutoTrackProtocol_h
|
||||
#define TAAutoTrackProtocol_h
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@protocol TDUIViewAutoTrackDelegate
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
UITableView event properties
|
||||
|
||||
@return event properties
|
||||
*/
|
||||
- (NSDictionary *)thinkingAnalytics_tableView:(UITableView *)tableView autoTrackPropertiesAtIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
/**
|
||||
APPID UITableView event properties
|
||||
|
||||
@return event properties
|
||||
*/
|
||||
- (NSDictionary *)thinkingAnalyticsWithAppid_tableView:(UITableView *)tableView autoTrackPropertiesAtIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
UICollectionView event properties
|
||||
|
||||
@return event properties
|
||||
*/
|
||||
- (NSDictionary *)thinkingAnalytics_collectionView:(UICollectionView *)collectionView autoTrackPropertiesAtIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
/**
|
||||
APPID UICollectionView event properties
|
||||
|
||||
@return event properties
|
||||
*/
|
||||
- (NSDictionary *)thinkingAnalyticsWithAppid_collectionView:(UICollectionView *)collectionView autoTrackPropertiesAtIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@protocol TDAutoTracker
|
||||
|
||||
@optional
|
||||
|
||||
- (NSDictionary *)getTrackProperties;
|
||||
|
||||
|
||||
- (NSDictionary *)getTrackPropertiesWithAppid;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
Automatically track the page
|
||||
*/
|
||||
@protocol TDScreenAutoTracker <TDAutoTracker>
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
Attributes for custom page view events
|
||||
*/
|
||||
- (NSString *)getScreenUrl;
|
||||
|
||||
/**
|
||||
Configure the properties of the APPID custom page view event
|
||||
*/
|
||||
- (NSDictionary *)getScreenUrlWithAppid;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* TAAutoTrackProtocol_h */
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f5cf0e391e1be6f4dae7d1d501d2efaa
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// TAAutoTrackPublicHeader.h
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by Yangxiongon 2022/7/1.
|
||||
//
|
||||
|
||||
#ifndef TAAutoTrackPublicHeader_h
|
||||
#define TAAutoTrackPublicHeader_h
|
||||
|
||||
#if __has_include(<ThinkingSDK/TAAutoTrackProtocol.h>)
|
||||
#import <ThinkingSDK/TAAutoTrackProtocol.h>
|
||||
#else
|
||||
#import "TAAutoTrackProtocol.h"
|
||||
#endif
|
||||
|
||||
#if __has_include(<ThinkingSDK/UIView+ThinkingAnalytics.h>)
|
||||
#import <ThinkingSDK/UIView+ThinkingAnalytics.h>
|
||||
#else
|
||||
#import "UIView+ThinkingAnalytics.h"
|
||||
#endif
|
||||
|
||||
#endif /* TAAutoTrackPublicHeader_h */
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5d98e43931f6fd4a8ccf60e1c84f678
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,34 @@
|
||||
#import "ThinkingAnalyticsSDK.h"
|
||||
#import "TDColdStartTracker.h"
|
||||
#import "TDHotStartTracker.h"
|
||||
#import "TDInstallTracker.h"
|
||||
|
||||
FOUNDATION_EXTERN NSString * const TD_EVENT_PROPERTY_TITLE;
|
||||
FOUNDATION_EXTERN NSString * const TD_EVENT_PROPERTY_URL_PROPERTY;
|
||||
FOUNDATION_EXTERN NSString * const TD_EVENT_PROPERTY_REFERRER_URL;
|
||||
FOUNDATION_EXTERN NSString * const TD_EVENT_PROPERTY_SCREEN_NAME;
|
||||
FOUNDATION_EXTERN NSString * const TD_EVENT_PROPERTY_ELEMENT_ID;
|
||||
FOUNDATION_EXTERN NSString * const TD_EVENT_PROPERTY_ELEMENT_TYPE;
|
||||
FOUNDATION_EXTERN NSString * const TD_EVENT_PROPERTY_ELEMENT_CONTENT;
|
||||
FOUNDATION_EXTERN NSString * const TD_EVENT_PROPERTY_ELEMENT_POSITION;
|
||||
|
||||
@interface TDAutoTrackManager : NSObject
|
||||
|
||||
+ (instancetype)sharedManager;
|
||||
|
||||
- (void)trackEventView:(UIView *)view;
|
||||
|
||||
- (void)trackEventView:(UIView *)view withIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
- (void)trackWithAppid:(NSString *)appid withOption:(ThinkingAnalyticsAutoTrackEventType)type;
|
||||
|
||||
- (void)viewControlWillAppear:(UIViewController *)controller;
|
||||
|
||||
+ (UIViewController *)topPresentedViewController;
|
||||
|
||||
#pragma mark - UNAVAILABLE
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8b472c2607fe7874b967a410a658ac97
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,764 @@
|
||||
#import "TDAutoTrackManager.h"
|
||||
|
||||
#import "TDSwizzler.h"
|
||||
#import "UIViewController+AutoTrack.h"
|
||||
#import "NSObject+TDSwizzle.h"
|
||||
#import "TDJSONUtil.h"
|
||||
#import "UIApplication+AutoTrack.h"
|
||||
#import "ThinkingAnalyticsSDKPrivate.h"
|
||||
#import "TDPublicConfig.h"
|
||||
#import "TAAutoClickEvent.h"
|
||||
#import "TAAutoPageViewEvent.h"
|
||||
#import "TAAppLifeCycle.h"
|
||||
#import "TDAppState.h"
|
||||
#import "TDRunTime.h"
|
||||
#import "TDPresetProperties+TDDisProperties.h"
|
||||
|
||||
#import "TAAppStartEvent.h"
|
||||
#import "TAAppEndEvent.h"
|
||||
#import "TDAppEndTracker.h"
|
||||
#import "TDColdStartTracker.h"
|
||||
#import "TDInstallTracker.h"
|
||||
#import "TDAppState.h"
|
||||
|
||||
#ifndef TD_LOCK
|
||||
#define TD_LOCK(lock) dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
|
||||
#endif
|
||||
|
||||
#ifndef TD_UNLOCK
|
||||
#define TD_UNLOCK(lock) dispatch_semaphore_signal(lock);
|
||||
#endif
|
||||
|
||||
NSString * const TD_EVENT_PROPERTY_TITLE = @"#title";
|
||||
NSString * const TD_EVENT_PROPERTY_URL_PROPERTY = @"#url";
|
||||
NSString * const TD_EVENT_PROPERTY_REFERRER_URL = @"#referrer";
|
||||
NSString * const TD_EVENT_PROPERTY_SCREEN_NAME = @"#screen_name";
|
||||
NSString * const TD_EVENT_PROPERTY_ELEMENT_ID = @"#element_id";
|
||||
NSString * const TD_EVENT_PROPERTY_ELEMENT_TYPE = @"#element_type";
|
||||
NSString * const TD_EVENT_PROPERTY_ELEMENT_CONTENT = @"#element_content";
|
||||
NSString * const TD_EVENT_PROPERTY_ELEMENT_POSITION = @"#element_position";
|
||||
|
||||
@interface TDAutoTrackManager ()
|
||||
@property (atomic, strong) NSMutableDictionary<NSString *, id> *autoTrackOptions;
|
||||
@property (nonatomic, strong, nonnull) dispatch_semaphore_t trackOptionLock;
|
||||
@property (atomic, copy) NSString *referrerViewControllerUrl;
|
||||
@property (nonatomic, strong) TDHotStartTracker *appHotStartTracker;
|
||||
@property (nonatomic, strong) TDAppEndTracker *appEndTracker;
|
||||
@property (nonatomic, strong) TDColdStartTracker *appColdStartTracker;
|
||||
@property (nonatomic, strong) TDInstallTracker *appInstallTracker;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation TDAutoTrackManager
|
||||
|
||||
#pragma mark - Public
|
||||
|
||||
+ (instancetype)sharedManager {
|
||||
static dispatch_once_t once;
|
||||
static TDAutoTrackManager *manager = nil;
|
||||
dispatch_once(&once, ^{
|
||||
manager = [[[TDAutoTrackManager class] alloc] init];
|
||||
manager.autoTrackOptions = [NSMutableDictionary new];
|
||||
manager.trackOptionLock = dispatch_semaphore_create(1);
|
||||
[manager registerAppLifeCycleListener];
|
||||
});
|
||||
return manager;
|
||||
}
|
||||
|
||||
- (void)trackEventView:(UIView *)view {
|
||||
[self trackEventView:view withIndexPath:nil];
|
||||
}
|
||||
|
||||
- (void)trackEventView:(UIView *)view withIndexPath:(NSIndexPath *)indexPath {
|
||||
if (view.thinkingAnalyticsIgnoreView) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *elementId = nil;
|
||||
NSString *elementType = nil;
|
||||
NSString *elementContent = nil;
|
||||
NSString *elementPosition = nil;
|
||||
NSString *elementPageTitle = nil;
|
||||
NSString *elementScreenName = nil;
|
||||
NSMutableDictionary *yx_customProperties = [NSMutableDictionary dictionary];
|
||||
|
||||
|
||||
elementId = view.thinkingAnalyticsViewID;
|
||||
elementType = NSStringFromClass([view class]);
|
||||
|
||||
|
||||
NSMutableDictionary *properties = [[NSMutableDictionary alloc] init];
|
||||
properties[TD_EVENT_PROPERTY_ELEMENT_ID] = view.thinkingAnalyticsViewID;
|
||||
properties[TD_EVENT_PROPERTY_ELEMENT_TYPE] = NSStringFromClass([view class]);
|
||||
UIViewController *viewController = [self viewControllerForView:view];
|
||||
if (viewController != nil) {
|
||||
NSString *screenName = NSStringFromClass([viewController class]);
|
||||
properties[TD_EVENT_PROPERTY_SCREEN_NAME] = screenName;
|
||||
|
||||
elementScreenName = screenName;
|
||||
|
||||
NSString *controllerTitle = [self titleFromViewController:viewController];
|
||||
if (controllerTitle) {
|
||||
properties[TD_EVENT_PROPERTY_TITLE] = controllerTitle;
|
||||
|
||||
elementPageTitle = controllerTitle;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NSDictionary *propDict = view.thinkingAnalyticsViewProperties;
|
||||
if ([propDict isKindOfClass:[NSDictionary class]]) {
|
||||
[properties addEntriesFromDictionary:propDict];
|
||||
|
||||
[yx_customProperties addEntriesFromDictionary:propDict];
|
||||
}
|
||||
|
||||
UIView *contentView;
|
||||
NSDictionary *propertyWithAppid;
|
||||
if (indexPath) {
|
||||
if ([view isKindOfClass:[UITableView class]]) {
|
||||
UITableView *tableView = (UITableView *)view;
|
||||
contentView = [tableView cellForRowAtIndexPath:indexPath];
|
||||
if (!contentView) {
|
||||
[tableView layoutIfNeeded];
|
||||
contentView = [tableView cellForRowAtIndexPath:indexPath];
|
||||
}
|
||||
properties[TD_EVENT_PROPERTY_ELEMENT_POSITION] = [NSString stringWithFormat: @"%ld:%ld", (unsigned long)indexPath.section, (unsigned long)indexPath.row];
|
||||
|
||||
elementPosition = [NSString stringWithFormat: @"%ld:%ld", (unsigned long)indexPath.section, (unsigned long)indexPath.row];
|
||||
|
||||
if ([tableView.thinkingAnalyticsDelegate conformsToProtocol:@protocol(TDUIViewAutoTrackDelegate)]) {
|
||||
if ([tableView.thinkingAnalyticsDelegate respondsToSelector:@selector(thinkingAnalytics_tableView:autoTrackPropertiesAtIndexPath:)]) {
|
||||
NSDictionary *dic = [view.thinkingAnalyticsDelegate thinkingAnalytics_tableView:tableView autoTrackPropertiesAtIndexPath:indexPath];
|
||||
if ([dic isKindOfClass:[NSDictionary class]]) {
|
||||
[properties addEntriesFromDictionary:dic];
|
||||
|
||||
[yx_customProperties addEntriesFromDictionary:dic];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ([tableView.thinkingAnalyticsDelegate respondsToSelector:@selector(thinkingAnalyticsWithAppid_tableView:autoTrackPropertiesAtIndexPath:)]) {
|
||||
propertyWithAppid = [view.thinkingAnalyticsDelegate thinkingAnalyticsWithAppid_tableView:tableView autoTrackPropertiesAtIndexPath:indexPath];
|
||||
}
|
||||
}
|
||||
} else if ([view isKindOfClass:[UICollectionView class]]) {
|
||||
UICollectionView *collectionView = (UICollectionView *)view;
|
||||
contentView = [collectionView cellForItemAtIndexPath:indexPath];
|
||||
if (!contentView) {
|
||||
[collectionView layoutIfNeeded];
|
||||
contentView = [collectionView cellForItemAtIndexPath:indexPath];
|
||||
}
|
||||
properties[TD_EVENT_PROPERTY_ELEMENT_POSITION] = [NSString stringWithFormat: @"%ld:%ld", (unsigned long)indexPath.section, (unsigned long)indexPath.row];
|
||||
|
||||
elementPosition = [NSString stringWithFormat: @"%ld:%ld", (unsigned long)indexPath.section, (unsigned long)indexPath.row];
|
||||
|
||||
if ([collectionView.thinkingAnalyticsDelegate conformsToProtocol:@protocol(TDUIViewAutoTrackDelegate)]) {
|
||||
if ([collectionView.thinkingAnalyticsDelegate respondsToSelector:@selector(thinkingAnalytics_collectionView:autoTrackPropertiesAtIndexPath:)]) {
|
||||
NSDictionary *dic = [view.thinkingAnalyticsDelegate thinkingAnalytics_collectionView:collectionView autoTrackPropertiesAtIndexPath:indexPath];
|
||||
if ([dic isKindOfClass:[NSDictionary class]]) {
|
||||
[properties addEntriesFromDictionary:dic];
|
||||
|
||||
[yx_customProperties addEntriesFromDictionary:dic];
|
||||
|
||||
}
|
||||
}
|
||||
if ([collectionView.thinkingAnalyticsDelegate respondsToSelector:@selector(thinkingAnalyticsWithAppid_collectionView:autoTrackPropertiesAtIndexPath:)]) {
|
||||
propertyWithAppid = [view.thinkingAnalyticsDelegate thinkingAnalyticsWithAppid_collectionView:collectionView autoTrackPropertiesAtIndexPath:indexPath];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
contentView = view;
|
||||
properties[TD_EVENT_PROPERTY_ELEMENT_POSITION] = [TDAutoTrackManager getPosition:contentView];
|
||||
|
||||
elementPosition = [TDAutoTrackManager getPosition:contentView];
|
||||
|
||||
}
|
||||
|
||||
NSString *content = [TDAutoTrackManager getText:contentView];
|
||||
if (content.length > 0) {
|
||||
properties[TD_EVENT_PROPERTY_ELEMENT_CONTENT] = content;
|
||||
|
||||
elementContent = content;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
NSDate *trackDate = [NSDate date];
|
||||
for (NSString *appid in self.autoTrackOptions) {
|
||||
|
||||
ThinkingAnalyticsAutoTrackEventType type = (ThinkingAnalyticsAutoTrackEventType)[self.autoTrackOptions[appid] integerValue];
|
||||
|
||||
if (type & ThinkingAnalyticsEventTypeAppClick) {
|
||||
|
||||
|
||||
|
||||
|
||||
ThinkingAnalyticsSDK *instance = [ThinkingAnalyticsSDK sharedInstanceWithAppid:appid];
|
||||
NSMutableDictionary *trackProperties = [properties mutableCopy];
|
||||
|
||||
NSMutableDictionary *yx_trackProperties = [yx_customProperties mutableCopy];
|
||||
|
||||
if ([instance isViewTypeIgnored:[view class]]) {
|
||||
continue;
|
||||
}
|
||||
NSDictionary *ignoreViews = view.thinkingAnalyticsIgnoreViewWithAppid;
|
||||
if (ignoreViews != nil && [[ignoreViews objectForKey:appid] isKindOfClass:[NSNumber class]]) {
|
||||
BOOL ignore = [[ignoreViews objectForKey:appid] boolValue];
|
||||
if (ignore)
|
||||
continue;
|
||||
}
|
||||
|
||||
if ([instance isViewControllerIgnored:viewController]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
NSDictionary *viewIDs = view.thinkingAnalyticsViewIDWithAppid;
|
||||
if (viewIDs != nil && [viewIDs objectForKey:appid]) {
|
||||
trackProperties[TD_EVENT_PROPERTY_ELEMENT_ID] = [viewIDs objectForKey:appid];
|
||||
|
||||
elementId = [viewIDs objectForKey:appid];
|
||||
|
||||
}
|
||||
|
||||
NSDictionary *viewProperties = view.thinkingAnalyticsViewPropertiesWithAppid;
|
||||
if (viewProperties != nil && [viewProperties objectForKey:appid]) {
|
||||
NSDictionary *properties = [viewProperties objectForKey:appid];
|
||||
if ([properties isKindOfClass:[NSDictionary class]]) {
|
||||
[trackProperties addEntriesFromDictionary:properties];
|
||||
|
||||
[yx_trackProperties addEntriesFromDictionary:properties];
|
||||
}
|
||||
}
|
||||
|
||||
if (propertyWithAppid) {
|
||||
NSDictionary *autoTrackproperties = [propertyWithAppid objectForKey:appid];
|
||||
if ([autoTrackproperties isKindOfClass:[NSDictionary class]]) {
|
||||
[trackProperties addEntriesFromDictionary:autoTrackproperties];
|
||||
|
||||
[yx_trackProperties addEntriesFromDictionary:autoTrackproperties];
|
||||
}
|
||||
}
|
||||
|
||||
TAAutoClickEvent *yx_event = [[TAAutoClickEvent alloc] initWithName:TD_APP_CLICK_EVENT];
|
||||
yx_event.time = trackDate;
|
||||
yx_event.elementId = elementId;
|
||||
yx_event.elementType = elementType;
|
||||
yx_event.elementContent = elementContent;
|
||||
yx_event.elementPosition = elementPosition;
|
||||
yx_event.pageTitle = elementPageTitle;
|
||||
yx_event.screenName = elementScreenName;
|
||||
|
||||
[instance autoTrackWithEvent:yx_event properties:yx_trackProperties];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)trackWithAppid:(NSString *)appid withOption:(ThinkingAnalyticsAutoTrackEventType)type {
|
||||
TD_LOCK(self.trackOptionLock);
|
||||
self.autoTrackOptions[appid] = @(type);
|
||||
TD_UNLOCK(self.trackOptionLock);
|
||||
|
||||
if (type & ThinkingAnalyticsEventTypeAppClick || type & ThinkingAnalyticsEventTypeAppViewScreen) {
|
||||
[self swizzleVC];
|
||||
}
|
||||
|
||||
if (type & ThinkingAnalyticsEventTypeAppInstall) {
|
||||
TAAutoTrackEvent *event = [[TAAutoTrackEvent alloc] initWithName:TD_APP_INSTALL_EVENT];
|
||||
event.time = [[NSDate date] dateByAddingTimeInterval: -1];
|
||||
[self.appInstallTracker trackWithInstanceTag:appid event:event params:nil];
|
||||
}
|
||||
|
||||
if (type & ThinkingAnalyticsEventTypeAppEnd) {
|
||||
ThinkingAnalyticsSDK *instance = [ThinkingAnalyticsSDK sharedInstanceWithAppid:appid];
|
||||
[instance timeEvent:TD_APP_END_EVENT];
|
||||
}
|
||||
|
||||
if (type & ThinkingAnalyticsEventTypeAppStart) {
|
||||
dispatch_block_t mainThreadBlock = ^(){
|
||||
NSString *eventName = [TDAppState shareInstance].relaunchInBackground ? TD_APP_START_BACKGROUND_EVENT : TD_APP_START_EVENT;
|
||||
TAAppStartEvent *event = [[TAAppStartEvent alloc] initWithName:eventName];
|
||||
event.resumeFromBackground = NO;
|
||||
if (![TDPresetProperties disableStartReason]) {
|
||||
NSString *reason = [TDRunTime getAppLaunchReason];
|
||||
if (reason && reason.length) {
|
||||
event.startReason = reason;
|
||||
}
|
||||
}
|
||||
[self.appColdStartTracker trackWithInstanceTag:appid event:event params:nil];
|
||||
};
|
||||
dispatch_async(dispatch_get_main_queue(), mainThreadBlock);
|
||||
}
|
||||
|
||||
if (type & ThinkingAnalyticsEventTypeAppViewCrash) {
|
||||
ThinkingAnalyticsSDK *instance = [ThinkingAnalyticsSDK sharedInstanceWithAppid:appid];
|
||||
[[ThinkingExceptionHandler sharedHandler] addThinkingInstance:instance];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)viewControlWillAppear:(UIViewController *)controller {
|
||||
[self trackViewController:controller];
|
||||
}
|
||||
|
||||
+ (UIViewController *)topPresentedViewController {
|
||||
UIWindow *keyWindow = [self findWindow];
|
||||
if (keyWindow != nil && !keyWindow.isKeyWindow) {
|
||||
[keyWindow makeKeyWindow];
|
||||
}
|
||||
|
||||
UIViewController *topController = keyWindow.rootViewController;
|
||||
if ([topController isKindOfClass:[UINavigationController class]]) {
|
||||
topController = [(UINavigationController *)topController topViewController];
|
||||
}
|
||||
while (topController.presentedViewController) {
|
||||
topController = topController.presentedViewController;
|
||||
}
|
||||
return topController;
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
- (BOOL)isAutoTrackEventType:(ThinkingAnalyticsAutoTrackEventType)eventType {
|
||||
BOOL isIgnored = YES;
|
||||
for (NSString *appid in self.autoTrackOptions) {
|
||||
ThinkingAnalyticsAutoTrackEventType type = (ThinkingAnalyticsAutoTrackEventType)[self.autoTrackOptions[appid] integerValue];
|
||||
isIgnored = !(type & eventType);
|
||||
if (isIgnored == NO)
|
||||
break;
|
||||
}
|
||||
return !isIgnored;
|
||||
}
|
||||
|
||||
- (UIViewController *)viewControllerForView:(UIView *)view {
|
||||
UIResponder *responder = view.nextResponder;
|
||||
while (responder) {
|
||||
if ([responder isKindOfClass:[UIViewController class]]) {
|
||||
if ([responder isKindOfClass:[UINavigationController class]]) {
|
||||
responder = [(UINavigationController *)responder topViewController];
|
||||
continue;
|
||||
} else if ([responder isKindOfClass:UITabBarController.class]) {
|
||||
responder = [(UITabBarController *)responder selectedViewController];
|
||||
continue;
|
||||
}
|
||||
return (UIViewController *)responder;
|
||||
}
|
||||
responder = responder.nextResponder;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)trackViewController:(UIViewController *)controller {
|
||||
if (![self shouldTrackViewContrller:[controller class]]) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *pageUrl = nil;
|
||||
NSString *pageReferrer = nil;
|
||||
NSString *pageTitle = nil;
|
||||
NSString *pageScreenName = nil;
|
||||
NSMutableDictionary *yx_customProperties = [NSMutableDictionary dictionary];
|
||||
|
||||
NSMutableDictionary *properties = [[NSMutableDictionary alloc] init];
|
||||
[properties setValue:NSStringFromClass([controller class]) forKey:TD_EVENT_PROPERTY_SCREEN_NAME];
|
||||
|
||||
pageScreenName = NSStringFromClass([controller class]);
|
||||
|
||||
NSString *controllerTitle = [self titleFromViewController:controller];
|
||||
if (controllerTitle) {
|
||||
[properties setValue:controllerTitle forKey:TD_EVENT_PROPERTY_TITLE];
|
||||
|
||||
pageTitle = controllerTitle;
|
||||
}
|
||||
|
||||
NSDictionary *autoTrackerAppidDic;
|
||||
if ([controller conformsToProtocol:@protocol(TDAutoTracker)]) {
|
||||
UIViewController<TDAutoTracker> *autoTrackerController = (UIViewController<TDAutoTracker> *)controller;
|
||||
NSDictionary *autoTrackerDic;
|
||||
if ([controller respondsToSelector:@selector(getTrackPropertiesWithAppid)])
|
||||
autoTrackerAppidDic = [autoTrackerController getTrackPropertiesWithAppid];
|
||||
if ([controller respondsToSelector:@selector(getTrackProperties)])
|
||||
autoTrackerDic = [autoTrackerController getTrackProperties];
|
||||
|
||||
if ([autoTrackerDic isKindOfClass:[NSDictionary class]]) {
|
||||
[properties addEntriesFromDictionary:autoTrackerDic];
|
||||
|
||||
[yx_customProperties addEntriesFromDictionary:autoTrackerDic];
|
||||
}
|
||||
}
|
||||
|
||||
NSDictionary *screenAutoTrackerAppidDic;
|
||||
if ([controller conformsToProtocol:@protocol(TDScreenAutoTracker)]) {
|
||||
UIViewController<TDScreenAutoTracker> *screenAutoTrackerController = (UIViewController<TDScreenAutoTracker> *)controller;
|
||||
if ([screenAutoTrackerController respondsToSelector:@selector(getScreenUrlWithAppid)])
|
||||
screenAutoTrackerAppidDic = [screenAutoTrackerController getScreenUrlWithAppid];
|
||||
if ([screenAutoTrackerController respondsToSelector:@selector(getScreenUrl)]) {
|
||||
NSString *currentUrl = [screenAutoTrackerController getScreenUrl];
|
||||
[properties setValue:currentUrl forKey:TD_EVENT_PROPERTY_URL_PROPERTY];
|
||||
|
||||
pageUrl = currentUrl;
|
||||
|
||||
[properties setValue:_referrerViewControllerUrl forKey:TD_EVENT_PROPERTY_REFERRER_URL];
|
||||
|
||||
pageReferrer = _referrerViewControllerUrl;
|
||||
|
||||
_referrerViewControllerUrl = currentUrl;
|
||||
}
|
||||
}
|
||||
|
||||
NSDate *trackDate = [NSDate date];
|
||||
for (NSString *appid in self.autoTrackOptions) {
|
||||
ThinkingAnalyticsAutoTrackEventType type = [self.autoTrackOptions[appid] integerValue];
|
||||
if (type & ThinkingAnalyticsEventTypeAppViewScreen) {
|
||||
|
||||
|
||||
|
||||
ThinkingAnalyticsSDK *instance = [ThinkingAnalyticsSDK sharedInstanceWithAppid:appid];
|
||||
NSMutableDictionary *trackProperties = [properties mutableCopy];
|
||||
|
||||
NSMutableDictionary *yx_trackProperties = [yx_customProperties mutableCopy];
|
||||
|
||||
if ([instance isViewControllerIgnored:controller]
|
||||
|| [instance isViewTypeIgnored:[controller class]]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (autoTrackerAppidDic && [autoTrackerAppidDic objectForKey:appid]) {
|
||||
NSDictionary *dic = [autoTrackerAppidDic objectForKey:appid];
|
||||
if ([dic isKindOfClass:[NSDictionary class]]) {
|
||||
[trackProperties addEntriesFromDictionary:dic];
|
||||
|
||||
[yx_trackProperties addEntriesFromDictionary:dic];
|
||||
}
|
||||
}
|
||||
|
||||
if (screenAutoTrackerAppidDic && [screenAutoTrackerAppidDic objectForKey:appid]) {
|
||||
NSString *screenUrl = [screenAutoTrackerAppidDic objectForKey:appid];
|
||||
[trackProperties setValue:screenUrl forKey:TD_EVENT_PROPERTY_URL_PROPERTY];
|
||||
|
||||
pageUrl = screenUrl;
|
||||
}
|
||||
|
||||
TAAutoPageViewEvent *pageEvent = [[TAAutoPageViewEvent alloc] initWithName:TD_APP_VIEW_EVENT];
|
||||
pageEvent.time = trackDate;
|
||||
pageEvent.pageUrl = pageUrl;
|
||||
pageEvent.pageTitle = pageTitle;
|
||||
pageEvent.referrer = pageReferrer;
|
||||
pageEvent.screenName = pageScreenName;
|
||||
|
||||
[instance autoTrackWithEvent:pageEvent properties:yx_trackProperties];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)shouldTrackViewContrller:(Class)aClass {
|
||||
return ![TDPublicConfig.controllers containsObject:NSStringFromClass(aClass)];
|
||||
}
|
||||
|
||||
- (ThinkingAnalyticsAutoTrackEventType)autoTrackOptionForAppid:(NSString *)appid {
|
||||
return (ThinkingAnalyticsAutoTrackEventType)[[self.autoTrackOptions objectForKey:appid] integerValue];
|
||||
}
|
||||
|
||||
- (void)swizzleSelected:(UIView *)view delegate:(id)delegate {
|
||||
if ([view isKindOfClass:[UITableView class]]
|
||||
&& [delegate conformsToProtocol:@protocol(UITableViewDelegate)]) {
|
||||
void (^block)(id, SEL, id, id) = ^(id target, SEL command, UITableView *tableView, NSIndexPath *indexPath) {
|
||||
[self trackEventView:tableView withIndexPath:indexPath];
|
||||
};
|
||||
|
||||
[TDSwizzler swizzleSelector:@selector(tableView:didSelectRowAtIndexPath:)
|
||||
onClass:[delegate class]
|
||||
withBlock:block
|
||||
named:@"td_table_select"];
|
||||
}
|
||||
|
||||
if ([view isKindOfClass:[UICollectionView class]]
|
||||
&& [delegate conformsToProtocol:@protocol(UICollectionViewDelegate)]) {
|
||||
|
||||
void (^block)(id, SEL, id, id) = ^(id target, SEL command, UICollectionView *collectionView, NSIndexPath *indexPath) {
|
||||
[self trackEventView:collectionView withIndexPath:indexPath];
|
||||
};
|
||||
[TDSwizzler swizzleSelector:@selector(collectionView:didSelectItemAtIndexPath:)
|
||||
onClass:[delegate class]
|
||||
withBlock:block
|
||||
named:@"td_collection_select"];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)swizzleVC {
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
void (^tableViewBlock)(UITableView *tableView,
|
||||
SEL cmd,
|
||||
id<UITableViewDelegate> delegate) =
|
||||
^(UITableView *tableView, SEL cmd, id<UITableViewDelegate> delegate) {
|
||||
if (!delegate) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self swizzleSelected:tableView delegate:delegate];
|
||||
};
|
||||
|
||||
[TDSwizzler swizzleSelector:@selector(setDelegate:)
|
||||
onClass:[UITableView class]
|
||||
withBlock:tableViewBlock
|
||||
named:@"td_table_delegate"];
|
||||
|
||||
void (^collectionViewBlock)(UICollectionView *, SEL, id<UICollectionViewDelegate>) = ^(UICollectionView *collectionView, SEL cmd, id<UICollectionViewDelegate> delegate) {
|
||||
if (nil == delegate) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self swizzleSelected:collectionView delegate:delegate];
|
||||
};
|
||||
[TDSwizzler swizzleSelector:@selector(setDelegate:)
|
||||
onClass:[UICollectionView class]
|
||||
withBlock:collectionViewBlock
|
||||
named:@"td_collection_delegate"];
|
||||
|
||||
|
||||
[UIViewController td_swizzleMethod:@selector(viewWillAppear:)
|
||||
withMethod:@selector(td_autotrack_viewWillAppear:)
|
||||
error:NULL];
|
||||
|
||||
[UIApplication td_swizzleMethod:@selector(sendAction:to:from:forEvent:)
|
||||
withMethod:@selector(td_sendAction:to:from:forEvent:)
|
||||
error:NULL];
|
||||
});
|
||||
}
|
||||
|
||||
+ (NSString *)getPosition:(UIView *)view {
|
||||
NSString *position = nil;
|
||||
if ([view isKindOfClass:[UIView class]] && view.thinkingAnalyticsIgnoreView) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
if ([view isKindOfClass:[UITabBar class]]) {
|
||||
UITabBar *tabbar = (UITabBar *)view;
|
||||
position = [NSString stringWithFormat: @"%ld", (long)[tabbar.items indexOfObject:tabbar.selectedItem]];
|
||||
} else if ([view isKindOfClass:[UISegmentedControl class]]) {
|
||||
UISegmentedControl *segment = (UISegmentedControl *)view;
|
||||
position = [NSString stringWithFormat:@"%ld", (long)segment.selectedSegmentIndex];
|
||||
} else if ([view isKindOfClass:[UIProgressView class]]) {
|
||||
UIProgressView *progress = (UIProgressView *)view;
|
||||
position = [NSString stringWithFormat:@"%f", progress.progress];
|
||||
} else if ([view isKindOfClass:[UIPageControl class]]) {
|
||||
UIPageControl *pageControl = (UIPageControl *)view;
|
||||
position = [NSString stringWithFormat:@"%ld", (long)pageControl.currentPage];
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
+ (NSString *)getText:(NSObject *)obj {
|
||||
NSString *text = nil;
|
||||
if ([obj isKindOfClass:[UIView class]] && [(UIView *)obj thinkingAnalyticsIgnoreView]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
if ([obj isKindOfClass:[UIButton class]]) {
|
||||
text = ((UIButton *)obj).currentTitle;
|
||||
} else if ([obj isKindOfClass:[UITextView class]] ||
|
||||
[obj isKindOfClass:[UITextField class]]) {
|
||||
//ignore
|
||||
} else if ([obj isKindOfClass:[UILabel class]]) {
|
||||
text = ((UILabel *)obj).text;
|
||||
} else if ([obj isKindOfClass:[UIPickerView class]]) {
|
||||
UIPickerView *picker = (UIPickerView *)obj;
|
||||
NSInteger sections = picker.numberOfComponents;
|
||||
NSMutableArray *titles = [NSMutableArray array];
|
||||
|
||||
for(NSInteger i = 0; i < sections; i++) {
|
||||
NSInteger row = [picker selectedRowInComponent:i];
|
||||
NSString *title;
|
||||
if ([picker.delegate
|
||||
respondsToSelector:@selector(pickerView:titleForRow:forComponent:)]) {
|
||||
title = [picker.delegate pickerView:picker titleForRow:row forComponent:i];
|
||||
} else if ([picker.delegate
|
||||
respondsToSelector:@selector(pickerView:attributedTitleForRow:forComponent:)]) {
|
||||
title = [picker.delegate
|
||||
pickerView:picker
|
||||
attributedTitleForRow:row forComponent:i].string;
|
||||
}
|
||||
[titles addObject:title ?: @""];
|
||||
}
|
||||
if (titles.count > 0) {
|
||||
text = [titles componentsJoinedByString:@","];
|
||||
}
|
||||
} else if ([obj isKindOfClass:[UIDatePicker class]]) {
|
||||
UIDatePicker *picker = (UIDatePicker *)obj;
|
||||
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
|
||||
formatter.dateFormat = kDefaultTimeFormat;
|
||||
text = [formatter stringFromDate:picker.date];
|
||||
} else if ([obj isKindOfClass:[UISegmentedControl class]]) {
|
||||
UISegmentedControl *segment = (UISegmentedControl *)obj;
|
||||
text = [NSString stringWithFormat:@"%@", [segment titleForSegmentAtIndex:segment.selectedSegmentIndex]];
|
||||
} else if ([obj isKindOfClass:[UISwitch class]]) {
|
||||
UISwitch *switchItem = (UISwitch *)obj;
|
||||
text = switchItem.on ? @"on" : @"off";
|
||||
} else if ([obj isKindOfClass:[UISlider class]]) {
|
||||
UISlider *slider = (UISlider *)obj;
|
||||
text = [NSString stringWithFormat:@"%f", [slider value]];
|
||||
} else if ([obj isKindOfClass:[UIStepper class]]) {
|
||||
UIStepper *step = (UIStepper *)obj;
|
||||
text = [NSString stringWithFormat:@"%f", [step value]];
|
||||
} else {
|
||||
if ([obj isKindOfClass:[UIView class]]) {
|
||||
for(UIView *subView in [(UIView *)obj subviews]) {
|
||||
text = [TDAutoTrackManager getText:subView];
|
||||
if ([text isKindOfClass:[NSString class]] && text.length > 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
- (NSString *)titleFromViewController:(UIViewController *)viewController {
|
||||
if (!viewController) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
UIView *titleView = viewController.navigationItem.titleView;
|
||||
NSString *elementContent = nil;
|
||||
if (titleView) {
|
||||
elementContent = [TDAutoTrackManager getText:titleView];
|
||||
}
|
||||
|
||||
return elementContent.length > 0 ? elementContent : viewController.navigationItem.title;
|
||||
}
|
||||
|
||||
+ (UIWindow *)findWindow {
|
||||
UIApplication *application = [TDAppState sharedApplication];
|
||||
if (![application isKindOfClass:UIApplication.class]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
UIWindow *window = application.keyWindow;
|
||||
if (window == nil || window.windowLevel != UIWindowLevelNormal) {
|
||||
for (window in application.windows) {
|
||||
if (window.windowLevel == UIWindowLevelNormal) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (@available(iOS 13.0, tvOS 13, *)) {
|
||||
NSSet *scenes = [[TDAppState sharedApplication] valueForKey:@"connectedScenes"];
|
||||
for (id scene in scenes) {
|
||||
if (window) {
|
||||
break;
|
||||
}
|
||||
|
||||
id activationState = [scene valueForKeyPath:@"activationState"];
|
||||
BOOL isActive = activationState != nil && [activationState integerValue] == 0;
|
||||
if (isActive) {
|
||||
Class WindowScene = NSClassFromString(@"UIWindowScene");
|
||||
if ([scene isKindOfClass:WindowScene]) {
|
||||
NSArray<UIWindow *> *windows = [scene valueForKeyPath:@"windows"];
|
||||
for (UIWindow *w in windows) {
|
||||
if (w.isKeyWindow) {
|
||||
window = w;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
//MARK: - App Life Cycle
|
||||
|
||||
- (void)registerAppLifeCycleListener {
|
||||
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
||||
|
||||
[notificationCenter addObserver:self selector:@selector(appStateWillChangeNotification:) name:kTAAppLifeCycleStateWillChangeNotification object:nil];
|
||||
}
|
||||
|
||||
- (void)appStateWillChangeNotification:(NSNotification *)notification {
|
||||
TAAppLifeCycleState newState = [[notification.userInfo objectForKey:kTAAppLifeCycleNewStateKey] integerValue];
|
||||
TAAppLifeCycleState oldState = [[notification.userInfo objectForKey:kTAAppLifeCycleOldStateKey] integerValue];
|
||||
|
||||
if (newState == TAAppLifeCycleStateStart) {
|
||||
for (NSString *appid in self.autoTrackOptions) {
|
||||
ThinkingAnalyticsAutoTrackEventType type = (ThinkingAnalyticsAutoTrackEventType)[self.autoTrackOptions[appid] integerValue];
|
||||
|
||||
// Only open the start event of collecting hot start. Cold start event, reported when automatic collection is turned on
|
||||
if ((type & ThinkingAnalyticsEventTypeAppStart) && oldState != TAAppLifeCycleStateInit) {
|
||||
NSString *eventName = [TDAppState shareInstance].relaunchInBackground ? TD_APP_START_BACKGROUND_EVENT : TD_APP_START_EVENT;
|
||||
TAAppStartEvent *event = [[TAAppStartEvent alloc] initWithName:eventName];
|
||||
event.resumeFromBackground = YES;
|
||||
|
||||
if (![TDPresetProperties disableStartReason]) {
|
||||
NSString *reason = [TDRunTime getAppLaunchReason];
|
||||
if (reason && reason.length) {
|
||||
event.startReason = reason;
|
||||
}
|
||||
}
|
||||
[self.appHotStartTracker trackWithInstanceTag:appid event:event params:@{}];
|
||||
}
|
||||
|
||||
if (type & ThinkingAnalyticsEventTypeAppEnd) {
|
||||
|
||||
ThinkingAnalyticsSDK *instance = [ThinkingAnalyticsSDK sharedInstanceWithAppid:appid];
|
||||
[instance timeEvent:TD_APP_END_EVENT];
|
||||
}
|
||||
}
|
||||
} else if (newState == TAAppLifeCycleStateEnd) {
|
||||
for (NSString *appid in self.autoTrackOptions) {
|
||||
ThinkingAnalyticsAutoTrackEventType type = (ThinkingAnalyticsAutoTrackEventType)[self.autoTrackOptions[appid] integerValue];
|
||||
if (type & ThinkingAnalyticsEventTypeAppEnd) {
|
||||
TAAppEndEvent *event = [[TAAppEndEvent alloc] initWithName:TD_APP_END_EVENT];
|
||||
td_dispatch_main_sync_safe(^{
|
||||
|
||||
NSString *screenName = NSStringFromClass([[TDAutoTrackManager topPresentedViewController] class]);
|
||||
event.screenName = screenName;
|
||||
[self.appEndTracker trackWithInstanceTag:appid event:event params:@{}];
|
||||
});
|
||||
}
|
||||
|
||||
if (type & ThinkingAnalyticsEventTypeAppStart) {
|
||||
ThinkingAnalyticsSDK *instance = [ThinkingAnalyticsSDK sharedInstanceWithAppid:appid];
|
||||
[instance timeEvent:TD_APP_START_EVENT];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - Getter & Setter
|
||||
|
||||
- (TDHotStartTracker *)appHotStartTracker {
|
||||
if (!_appHotStartTracker) {
|
||||
_appHotStartTracker = [[TDHotStartTracker alloc] init];
|
||||
}
|
||||
return _appHotStartTracker;
|
||||
}
|
||||
|
||||
- (TDColdStartTracker *)appColdStartTracker {
|
||||
if (!_appColdStartTracker) {
|
||||
_appColdStartTracker = [[TDColdStartTracker alloc] init];
|
||||
}
|
||||
return _appColdStartTracker;
|
||||
}
|
||||
|
||||
- (TDInstallTracker *)appInstallTracker {
|
||||
if (!_appInstallTracker) {
|
||||
_appInstallTracker = [[TDInstallTracker alloc] init];
|
||||
}
|
||||
return _appInstallTracker;
|
||||
}
|
||||
|
||||
- (TDAppEndTracker *)appEndTracker {
|
||||
if (!_appEndTracker) {
|
||||
_appEndTracker = [[TDAppEndTracker alloc] init];
|
||||
}
|
||||
return _appEndTracker;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e28ed5bde9eff6e4ead5f94647ed98c3
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 462bc89e58151374fbaed6eab40f2d41
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// TDAppEndTracker.h
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by Yangxiongon 2022/6/16.
|
||||
//
|
||||
|
||||
#import "TDAutoTracker.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TDAppEndTracker : TDAutoTracker
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ab31df7ede2aa184285f3bd836116e7a
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,12 @@
|
||||
//
|
||||
// TDAppEndTracker.m
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by Yangxiongon 2022/6/16.
|
||||
//
|
||||
|
||||
#import "TDAppEndTracker.h"
|
||||
|
||||
@implementation TDAppEndTracker
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a3a631587e8c0741954d648c11fd3ec
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// TDAutoTracker.h
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by wwango on 2021/10/13.
|
||||
// Copyright © 2021 thinkingdata. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "ThinkingAnalyticsSDK.h"
|
||||
#import "TAAutoTrackEvent.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TDAutoTracker : NSObject
|
||||
|
||||
@property (atomic, assign) BOOL isOneTime;
|
||||
|
||||
@property (atomic, assign) BOOL autoFlush;
|
||||
|
||||
@property (atomic, assign) BOOL additionalCondition;
|
||||
|
||||
- (void)trackWithInstanceTag:(NSString *)instanceName event:(TAAutoTrackEvent *)event params:(nullable NSDictionary *)params;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 474c41104156fac46955dcbb252c69ea
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,67 @@
|
||||
//
|
||||
// TDAutoTracker.m
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by wwango on 2021/10/13.
|
||||
// Copyright © 2021 thinkingdata. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TDAutoTracker.h"
|
||||
#import "ThinkingAnalyticsSDKPrivate.h"
|
||||
|
||||
@interface TDAutoTracker ()
|
||||
|
||||
@property (nonatomic, strong) NSMutableDictionary<NSString *, NSNumber *> *trackCounts;
|
||||
|
||||
@end
|
||||
|
||||
@implementation TDAutoTracker
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_isOneTime = NO;
|
||||
_autoFlush = YES;
|
||||
_additionalCondition = YES;
|
||||
|
||||
self.trackCounts = [NSMutableDictionary dictionary];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)trackWithInstanceTag:(NSString *)instanceName event:(TAAutoTrackEvent *)event params:(NSDictionary *)params {
|
||||
if ([self canTrackWithInstanceToken:instanceName]) {
|
||||
ThinkingAnalyticsSDK *instance = [ThinkingAnalyticsSDK sharedInstanceWithAppid:instanceName];
|
||||
#ifdef DEBUG
|
||||
if (!instance) {
|
||||
@throw [NSException exceptionWithName:@"Thinkingdata Exception" reason:[NSString stringWithFormat:@"check this thinking instance, instanceTag: %@", instanceName] userInfo:nil];
|
||||
}
|
||||
#endif
|
||||
[instance autoTrackWithEvent:event properties:params];
|
||||
|
||||
if (self.autoFlush) [instance flush];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)canTrackWithInstanceToken:(NSString *)token {
|
||||
|
||||
if (!self.additionalCondition) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSInteger trackCount = [self.trackCounts[token] integerValue];
|
||||
|
||||
if (self.isOneTime && trackCount >= 1) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (self.isOneTime) {
|
||||
trackCount++;
|
||||
self.trackCounts[token] = @(trackCount);
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4c3592f187e49044e9af02246ae39d74
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// TDColdStartTracker.h
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by Yangxiongon 2022/7/1.
|
||||
//
|
||||
|
||||
#import "TDAutoTracker.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TDColdStartTracker : TDAutoTracker
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 50b8dbdd05dbf5140b35a61ce964b9bc
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// TDColdStartTracker.m
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by Yangxiongon 2022/7/1.
|
||||
//
|
||||
|
||||
#import "TDColdStartTracker.h"
|
||||
|
||||
@implementation TDColdStartTracker
|
||||
|
||||
- (instancetype)init {
|
||||
if (self = [super init]) {
|
||||
self.isOneTime = YES;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aeb40d37805f0f144ac7a1ad54ddc002
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// TDHotStartTracker.h
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by Yangxiongon 2022/7/1.
|
||||
//
|
||||
|
||||
#import "TDAutoTracker.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TDHotStartTracker : TDAutoTracker
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e58eeefebbc316246ab90b1315c79eaa
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,12 @@
|
||||
//
|
||||
// TDHotStartTracker.m
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by Yangxiongon 2022/7/1.
|
||||
//
|
||||
|
||||
#import "TDHotStartTracker.h"
|
||||
|
||||
@implementation TDHotStartTracker
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f47fcc87472a6bc408fd5c7f132fc9f4
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// TDInstallTracker.h
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by wwango on 2021/10/13.
|
||||
// Copyright © 2021 thinkingdata. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TDAutoTracker.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TDInstallTracker : TDAutoTracker
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4fd599bc5ddf3e540985439a2c683254
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// TDInstallTracker.m
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by wwango on 2021/10/13.
|
||||
// Copyright © 2021 thinkingdata. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TDInstallTracker.h"
|
||||
#import "TDDeviceInfo.h"
|
||||
|
||||
@implementation TDInstallTracker
|
||||
|
||||
- (BOOL)isOneTime {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)additionalCondition {
|
||||
return [TDDeviceInfo sharedManager].isFirstOpen;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8b55c1946deacef4fb3b8d68e0e9cd18
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b80d07502d2a4be4d875233ba8604a5b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,14 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface UIApplication (AutoTrack)
|
||||
|
||||
- (BOOL)td_sendAction:(SEL)action
|
||||
to:(nullable id)to
|
||||
from:(nullable id)from
|
||||
forEvent:(nullable UIEvent *)event;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 76827556b4c29d74b9d9866d1532361a
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,24 @@
|
||||
#import "UIApplication+AutoTrack.h"
|
||||
#import "TDAutoTrackManager.h"
|
||||
|
||||
@implementation UIApplication (AutoTrack)
|
||||
|
||||
- (BOOL)td_sendAction:(SEL)action to:(id)to from:(id)from forEvent:(UIEvent *)event {
|
||||
if ([from isKindOfClass:[UIControl class]]) {
|
||||
if (([from isKindOfClass:[UISwitch class]] ||
|
||||
[from isKindOfClass:[UISegmentedControl class]] ||
|
||||
[from isKindOfClass:[UIStepper class]])) {
|
||||
[[TDAutoTrackManager sharedManager] trackEventView:from];
|
||||
}
|
||||
|
||||
else if ([event isKindOfClass:[UIEvent class]] &&
|
||||
event.type == UIEventTypeTouches &&
|
||||
[[[event allTouches] anyObject] phase] == UITouchPhaseEnded) {
|
||||
[[TDAutoTrackManager sharedManager] trackEventView:from];
|
||||
}
|
||||
}
|
||||
|
||||
return [self td_sendAction:action to:to from:from forEvent:event];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e342b8a785318f428bfd623fa57d1da
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// UIView+ThinkingAnalytics.h
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by Yangxiongon 2022/7/1.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface UIView (ThinkingAnalytics)
|
||||
|
||||
/**
|
||||
Set the control element ID
|
||||
*/
|
||||
@property (copy,nonatomic) NSString *thinkingAnalyticsViewID;
|
||||
|
||||
/**
|
||||
Configure the control element ID of APPID
|
||||
*/
|
||||
@property (strong,nonatomic) NSDictionary *thinkingAnalyticsViewIDWithAppid;
|
||||
|
||||
/**
|
||||
Ignore the click event of a control
|
||||
*/
|
||||
@property (nonatomic,assign) BOOL thinkingAnalyticsIgnoreView;
|
||||
|
||||
/**
|
||||
Configure APPID to ignore the click event of a control
|
||||
*/
|
||||
@property (strong,nonatomic) NSDictionary *thinkingAnalyticsIgnoreViewWithAppid;
|
||||
|
||||
/**
|
||||
Properties of custom control click event
|
||||
*/
|
||||
@property (strong,nonatomic) NSDictionary *thinkingAnalyticsViewProperties;
|
||||
|
||||
/**
|
||||
Configure the properties of the APPID custom control click event
|
||||
*/
|
||||
@property (strong,nonatomic) NSDictionary *thinkingAnalyticsViewPropertiesWithAppid;
|
||||
|
||||
/**
|
||||
thinkingAnalyticsDelegate
|
||||
*/
|
||||
@property (nonatomic, weak, nullable) id thinkingAnalyticsDelegate;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c67fc5d11c1b49f48b6d63493119861d
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,77 @@
|
||||
//
|
||||
// UIView+ThinkingAnalytics.m
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by Yangxiongon 2022/7/1.
|
||||
//
|
||||
|
||||
#import "UIView+ThinkingAnalytics.h"
|
||||
#import <objc/runtime.h>
|
||||
|
||||
static char TD_AUTOTRACK_VIEW_ID;
|
||||
static char TD_AUTOTRACK_VIEW_ID_APPID;
|
||||
static char TD_AUTOTRACK_VIEW_IGNORE;
|
||||
static char TD_AUTOTRACK_VIEW_IGNORE_APPID;
|
||||
static char TD_AUTOTRACK_VIEW_PROPERTIES;
|
||||
static char TD_AUTOTRACK_VIEW_PROPERTIES_APPID;
|
||||
static char TD_AUTOTRACK_VIEW_DELEGATE;
|
||||
|
||||
@implementation UIView (ThinkingAnalytics)
|
||||
|
||||
- (NSString *)thinkingAnalyticsViewID {
|
||||
return objc_getAssociatedObject(self, &TD_AUTOTRACK_VIEW_ID);
|
||||
}
|
||||
|
||||
- (void)setThinkingAnalyticsViewID:(NSString *)thinkingAnalyticsViewID {
|
||||
objc_setAssociatedObject(self, &TD_AUTOTRACK_VIEW_ID, thinkingAnalyticsViewID, OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||
}
|
||||
|
||||
- (BOOL)thinkingAnalyticsIgnoreView {
|
||||
return [objc_getAssociatedObject(self, &TD_AUTOTRACK_VIEW_IGNORE) boolValue];
|
||||
}
|
||||
|
||||
- (void)setThinkingAnalyticsIgnoreView:(BOOL)thinkingAnalyticsIgnoreView {
|
||||
objc_setAssociatedObject(self, &TD_AUTOTRACK_VIEW_IGNORE, [NSNumber numberWithBool:thinkingAnalyticsIgnoreView], OBJC_ASSOCIATION_ASSIGN);
|
||||
}
|
||||
|
||||
- (NSDictionary *)thinkingAnalyticsIgnoreViewWithAppid {
|
||||
return objc_getAssociatedObject(self, &TD_AUTOTRACK_VIEW_IGNORE_APPID);
|
||||
}
|
||||
|
||||
- (void)setThinkingAnalyticsIgnoreViewWithAppid:(NSDictionary *)thinkingAnalyticsViewProperties {
|
||||
objc_setAssociatedObject(self, &TD_AUTOTRACK_VIEW_IGNORE_APPID, thinkingAnalyticsViewProperties, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (NSDictionary *)thinkingAnalyticsViewIDWithAppid {
|
||||
return objc_getAssociatedObject(self, &TD_AUTOTRACK_VIEW_ID_APPID);
|
||||
}
|
||||
|
||||
- (void)setThinkingAnalyticsViewIDWithAppid:(NSDictionary *)thinkingAnalyticsViewProperties {
|
||||
objc_setAssociatedObject(self, &TD_AUTOTRACK_VIEW_ID_APPID, thinkingAnalyticsViewProperties, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (NSDictionary *)thinkingAnalyticsViewProperties {
|
||||
return objc_getAssociatedObject(self, &TD_AUTOTRACK_VIEW_PROPERTIES);
|
||||
}
|
||||
|
||||
- (void)setThinkingAnalyticsViewProperties:(NSDictionary *)thinkingAnalyticsViewProperties {
|
||||
objc_setAssociatedObject(self, &TD_AUTOTRACK_VIEW_PROPERTIES, thinkingAnalyticsViewProperties, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (NSDictionary *)thinkingAnalyticsViewPropertiesWithAppid {
|
||||
return objc_getAssociatedObject(self, &TD_AUTOTRACK_VIEW_PROPERTIES_APPID);
|
||||
}
|
||||
|
||||
- (void)setThinkingAnalyticsViewPropertiesWithAppid:(NSDictionary *)thinkingAnalyticsViewProperties {
|
||||
objc_setAssociatedObject(self, &TD_AUTOTRACK_VIEW_PROPERTIES_APPID, thinkingAnalyticsViewProperties, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (id)thinkingAnalyticsDelegate {
|
||||
return objc_getAssociatedObject(self, &TD_AUTOTRACK_VIEW_DELEGATE);
|
||||
}
|
||||
|
||||
- (void)setThinkingAnalyticsDelegate:(id)thinkingAnalyticsDelegate {
|
||||
objc_setAssociatedObject(self, &TD_AUTOTRACK_VIEW_DELEGATE, thinkingAnalyticsDelegate, OBJC_ASSOCIATION_ASSIGN);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a3caba30b926a2441ae7a9a0b657b4e5
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface UIViewController (AutoTrack)
|
||||
|
||||
- (void)td_autotrack_viewWillAppear:(BOOL)animated;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c7a1ed12078ed9c4ba5c3e3587346e4e
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,16 @@
|
||||
#import "UIViewController+AutoTrack.h"
|
||||
#import "TDAutoTrackManager.h"
|
||||
#import "TDLogging.h"
|
||||
|
||||
@implementation UIViewController (AutoTrack)
|
||||
|
||||
- (void)td_autotrack_viewWillAppear:(BOOL)animated {
|
||||
@try {
|
||||
[[TDAutoTrackManager sharedManager] viewControlWillAppear:self];
|
||||
} @catch (NSException *exception) {
|
||||
TDLogError(@"%@ error: %@", self, exception);
|
||||
}
|
||||
[self td_autotrack_viewWillAppear:animated];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 081cc82a073a6aa489fa263acf6f362a
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user