Ta android + ios

This commit is contained in:
LYP
2024-08-07 20:22:28 +08:00
parent 69fee08c61
commit 76458664d8
722 changed files with 41709 additions and 1 deletions

View File

@@ -0,0 +1,47 @@
//
// TAAppLifeCycle.h
// ThinkingSDK
//
// Created by Yangxiongon 2022/6/28.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/// APP life cycle
typedef NS_ENUM(NSUInteger, TAAppLifeCycleState) {
TAAppLifeCycleStateInit = 1, // init status
TAAppLifeCycleStateBackgroundStart,
TAAppLifeCycleStateStart,
TAAppLifeCycleStateEnd,
TAAppLifeCycleStateTerminate,
};
/// When the life cycle status is about to change, this notification will be sent
/// object: The object is the current life cycle object
/// userInfo: Contains two keys kTAAppLifeCycleNewStateKey and kTAAppLifeCycleOldStateKey
extern NSNotificationName const kTAAppLifeCycleStateWillChangeNotification;
/// When the life cycle status changes, this notification will be sent
/// object: The object is the current lifecycle object
/// userInfo: Contains two keys kTAAppLifeCycleNewStateKey and kTAAppLifeCycleOldStateKey
extern NSNotificationName const kTAAppLifeCycleStateDidChangeNotification;
/// In the status change notification, get the new status
extern NSString * const kTAAppLifeCycleNewStateKey;
/// In the status change notification, get the status before the change
extern NSString * const kTAAppLifeCycleOldStateKey;
@interface TAAppLifeCycle : NSObject
@property (nonatomic, assign, readonly) TAAppLifeCycleState state;
+ (void)startMonitor;
+ (instancetype)shareInstance;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: 610fdfd3759c45f439e92e6bf7db0aa2
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:

View File

@@ -0,0 +1,246 @@
//
// TAAppLifeCycle.m
// ThinkingSDK
//
// Created by Yangxiongon 2022/6/28.
//
#import "TAAppLifeCycle.h"
#import "TDAppState.h"
#if TARGET_OS_IOS
#import <UIKit/UIKit.h>
#endif
#if __has_include(<ThinkingSDK/TDLogging.h>)
#import <ThinkingSDK/TDLogging.h>
#else
#import "TDLogging.h"
#endif
NSNotificationName const kTAAppLifeCycleStateWillChangeNotification = @"cn.thinkingdata.TAAppLifeCycleStateWillChange";
NSNotificationName const kTAAppLifeCycleStateDidChangeNotification = @"cn.thinkingdata.TAAppLifeCycleStateDidChange";
NSString * const kTAAppLifeCycleNewStateKey = @"new";
NSString * const kTAAppLifeCycleOldStateKey = @"old";
@interface TAAppLifeCycle ()
/// status
@property (nonatomic, assign) TAAppLifeCycleState state;
@end
@implementation TAAppLifeCycle
+ (void)startMonitor {
[TAAppLifeCycle shareInstance];
}
+ (instancetype)shareInstance {
static dispatch_once_t onceToken;
static TAAppLifeCycle *appLifeCycle = nil;
dispatch_once(&onceToken, ^{
appLifeCycle = [[TAAppLifeCycle alloc] init];
});
return appLifeCycle;
}
- (instancetype)init {
self = [super init];
if (self) {
_state = TAAppLifeCycleStateInit;
[self registerListeners];
[self setupLaunchedState];
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)registerListeners {
if ([TDAppState runningInAppExtension]) {
return;
}
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
#if TARGET_OS_IOS
[notificationCenter addObserver:self
selector:@selector(applicationDidBecomeActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
[notificationCenter addObserver:self
selector:@selector(applicationDidEnterBackground:)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
[notificationCenter addObserver:self
selector:@selector(applicationWillTerminate:)
name:UIApplicationWillTerminateNotification
object:nil];
#elif TARGET_OS_OSX
// [notificationCenter addObserver:self
// selector:@selector(applicationDidFinishLaunching:)
// name:NSApplicationDidFinishLaunchingNotification
// object:nil];
//
// [notificationCenter addObserver:self
// selector:@selector(applicationDidBecomeActive:)
// name:NSApplicationDidBecomeActiveNotification
// object:nil];
// [notificationCenter addObserver:self
// selector:@selector(applicationDidResignActive:)
// name:NSApplicationDidResignActiveNotification
// object:nil];
//
// [notificationCenter addObserver:self
// selector:@selector(applicationWillTerminate:)
// name:NSApplicationWillTerminateNotification
// object:nil];
#endif
}
- (void)setupLaunchedState {
if ([TDAppState runningInAppExtension]) {
return;
}
dispatch_block_t mainThreadBlock = ^(){
#if TARGET_OS_IOS
UIApplication *application = [TDAppState sharedApplication];
BOOL isAppStateBackground = application.applicationState == UIApplicationStateBackground;
#else
BOOL isAppStateBackground = NO;
#endif
[TDAppState shareInstance].relaunchInBackground = isAppStateBackground;
self.state = isAppStateBackground ? TAAppLifeCycleStateBackgroundStart : TAAppLifeCycleStateStart;
};
if (@available(iOS 13.0, *)) {
// The reason why iOS 13 and above modify the status in the block of the asynchronous main queue:+
// 1. Make sure that the initialization of the SDK has been completed before sending the appstatus change notification. This can ensure that the public properties have been set when the automatic collection management class sends the app_start event (in fact, it can also be achieved by listening to UIApplicationDidFinishLaunchingNotification)
// 2. In a project that contains SceneDelegate, it is accurate to delay obtaining applicationState (obtaining by listening to UIApplicationDidFinishLaunchingNotification is inaccurate)
dispatch_async(dispatch_get_main_queue(), mainThreadBlock);
} else {
// iOS 13 and below handle background wakeup and cold start (non-delayed initialization) by listening to the notification of UIApplicationDidFinishLaunchingNotification:
// 1. When iOS 13 or later wakes up in the background, the block of the asynchronous main queue will not be executed. So you need to listen to UIApplicationDidFinishLaunchingNotification at the same time
// 2. iOS 13 and below will not contain SceneDelegate
#if TARGET_OS_IOS
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidFinishLaunching:)
name:UIApplicationDidFinishLaunchingNotification
object:nil];
#endif
// Handle cold start below iOS 13, where the client delays initialization. UIApplicationDidFinishLaunchingNotification notification has been missed when lazy initialization
dispatch_async(dispatch_get_main_queue(), mainThreadBlock);
}
}
//MARK: - Notification Action
- (void)applicationDidFinishLaunching:(NSNotification *)notification {
#if TARGET_OS_IOS
UIApplication *application = [TDAppState sharedApplication];
BOOL isAppStateBackground = application.applicationState == UIApplicationStateBackground;
#else
BOOL isAppStateBackground = NO;
#endif
[TDAppState shareInstance].relaunchInBackground = isAppStateBackground;
self.state = isAppStateBackground ? TAAppLifeCycleStateBackgroundStart : TAAppLifeCycleStateStart;
}
- (void)applicationDidBecomeActive:(NSNotification *)notification {
TDLogDebug(@"application did become active");
#if TARGET_OS_IOS
if (![notification.object isKindOfClass:[UIApplication class]]) {
return;
}
UIApplication *application = (UIApplication *)notification.object;
if (application.applicationState != UIApplicationStateActive) {
return;
}
#elif TARGET_OS_OSX
if (![notification.object isKindOfClass:[NSApplication class]]) {
return;
}
NSApplication *application = (NSApplication *)notification.object;
if (!application.isActive) {
return;
}
#endif
[TDAppState shareInstance].relaunchInBackground = NO;
self.state = TAAppLifeCycleStateStart;
}
#if TARGET_OS_IOS
- (void)applicationDidEnterBackground:(NSNotification *)notification {
TDLogDebug(@"application did enter background");
if (![notification.object isKindOfClass:[UIApplication class]]) {
return;
}
UIApplication *application = (UIApplication *)notification.object;
if (application.applicationState != UIApplicationStateBackground) {
return;
}
self.state = TAAppLifeCycleStateEnd;
}
#elif TARGET_OS_OSX
- (void)applicationDidResignActive:(NSNotification *)notification {
TDLogDebug(@"application did resignActive");
if (![notification.object isKindOfClass:[NSApplication class]]) {
return;
}
NSApplication *application = (NSApplication *)notification.object;
if (application.isActive) {
return;
}
self.state = TAAppLifeCycleStateEnd;
}
#endif
- (void)applicationWillTerminate:(NSNotification *)notification {
TDLogDebug(@"application will terminate");
self.state = TAAppLifeCycleStateTerminate;
}
//MARK: - Setter
- (void)setState:(TAAppLifeCycleState)state {
if (_state == state) {
return;
}
[TDAppState shareInstance].isActive = (state == TAAppLifeCycleStateStart);
NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithCapacity:2];
userInfo[kTAAppLifeCycleNewStateKey] = @(state);
userInfo[kTAAppLifeCycleOldStateKey] = @(_state);
[[NSNotificationCenter defaultCenter] postNotificationName:kTAAppLifeCycleStateWillChangeNotification object:self userInfo:userInfo];
_state = state;
[[NSNotificationCenter defaultCenter] postNotificationName:kTAAppLifeCycleStateDidChangeNotification object:self userInfo:userInfo];
}
@end

View File

@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: c63bdf355fa2241419ab65c6105d3acf
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:

View File

@@ -0,0 +1,28 @@
//
// TDAppState.h
// ThinkingSDK
//
// Created by wwango on 2021/9/24.
// Copyright © 2021 thinkingdata. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface TDAppState : NSObject
/// Whether to start in the background. When the app is woken up by silently pushing the background, or when the location change wakes up the app, value = YES. (thread safe)
@property (atomic, assign) BOOL relaunchInBackground;
/// Whether the current app is in the foreground
@property (atomic, assign) BOOL isActive;
+ (instancetype)shareInstance;
+ (id)sharedApplication;
+ (BOOL)runningInAppExtension;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: c75a2cc6ed1843642a1e845ac0df06f8
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:

View File

@@ -0,0 +1,48 @@
//
// TDAppState.m
// ThinkingSDK
//
// Created by wwango on 2021/9/24.
// Copyright © 2021 thinkingdata. All rights reserved.
//
#import "TDAppState.h"
#if TARGET_OS_IOS
#import <UIKit/UIKit.h>
#endif
NSString *_td_lastKnownState;
@implementation TDAppState
+ (instancetype)shareInstance {
static dispatch_once_t onceToken;
static TDAppState *appState;
dispatch_once(&onceToken, ^{
appState = [TDAppState new];
});
return appState;
}
+ (id)sharedApplication {
#if TARGET_OS_IOS
if ([self runningInAppExtension]) {
return nil;
}
return [[UIApplication class] performSelector:@selector(sharedApplication)];
#endif
return nil;
}
+ (BOOL)runningInAppExtension {
#if TARGET_OS_IOS
return [[[[NSBundle mainBundle] bundlePath] pathExtension] isEqualToString:@"appex"];
#endif
return NO;
}
@end

View File

@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: 624b80054b0aaa046bd67b8df72def6f
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: