327 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Mathematica
		
	
	
	
		
		
			
		
	
	
			327 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Mathematica
		
	
	
	
|  | #import "TDConfig.h"
 | ||
|  | 
 | ||
|  | #import "TDAnalyticsNetwork.h"
 | ||
|  | #import "ThinkingAnalyticsSDKPrivate.h"
 | ||
|  | #import "TDSecurityPolicy.h"
 | ||
|  | #import "TDFile.h"
 | ||
|  | #import "TDConfigPrivate.h"
 | ||
|  | 
 | ||
|  | #if __has_include(<ThinkingDataCore/TDCalibratedTime.h>)
 | ||
|  | #import <ThinkingDataCore/TDCalibratedTime.h>
 | ||
|  | #else
 | ||
|  | #import "TDCalibratedTime.h"
 | ||
|  | #endif
 | ||
|  | #if __has_include(<ThinkingDataCore/NSString+TDCore.h>)
 | ||
|  | #import <ThinkingDataCore/NSString+TDCore.h>
 | ||
|  | #else
 | ||
|  | #import "NSString+TDCore.h"
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #define TDSDKSETTINGS_PLIST_SETTING_IMPL(TYPE, PLIST_KEY, GETTER, SETTER, DEFAULT_VALUE, ENABLE_CACHE) \
 | ||
|  | static TYPE *g_##PLIST_KEY = nil; \
 | ||
|  | + (TYPE *)GETTER \
 | ||
|  | { \
 | ||
|  |   if (!g_##PLIST_KEY && ENABLE_CACHE) { \
 | ||
|  |     g_##PLIST_KEY = [[[NSUserDefaults standardUserDefaults] objectForKey:@#PLIST_KEY] copy]; \
 | ||
|  |   } \
 | ||
|  |   if (!g_##PLIST_KEY) { \
 | ||
|  |     g_##PLIST_KEY = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@#PLIST_KEY] copy] ?: DEFAULT_VALUE; \
 | ||
|  |   } \
 | ||
|  |   return g_##PLIST_KEY; \
 | ||
|  | } \
 | ||
|  | + (void)SETTER:(TYPE *)value { \
 | ||
|  |   g_##PLIST_KEY = [value copy]; \
 | ||
|  |   if (ENABLE_CACHE) { \
 | ||
|  |     if (value) { \
 | ||
|  |       [[NSUserDefaults standardUserDefaults] setObject:value forKey:@#PLIST_KEY]; \
 | ||
|  |     } else { \
 | ||
|  |       [[NSUserDefaults standardUserDefaults] removeObjectForKey:@#PLIST_KEY]; \
 | ||
|  |     } \
 | ||
|  |   } \
 | ||
|  | }
 | ||
|  | 
 | ||
|  | 
 | ||
|  | #define kTAConfigInfo @"TAConfigInfo"
 | ||
|  | 
 | ||
|  | static NSDictionary *configInfo;
 | ||
|  | 
 | ||
|  | @interface TDConfig ()
 | ||
|  | @property (nonatomic, assign) ThinkingNetworkType innerNetworkType;
 | ||
|  | 
 | ||
|  | @end
 | ||
|  | 
 | ||
|  | @implementation TDConfig
 | ||
|  | 
 | ||
|  | TDSDKSETTINGS_PLIST_SETTING_IMPL(NSNumber, ThinkingSDKMaxCacheSize, _maxNumEventsNumber, _setMaxNumEventsNumber, @10000, NO);
 | ||
|  | TDSDKSETTINGS_PLIST_SETTING_IMPL(NSNumber, ThinkingSDKExpirationDays, _expirationDaysNumber, _setExpirationDaysNumber, @10, NO);
 | ||
|  | 
 | ||
|  | - (instancetype)init {
 | ||
|  |     self = [super init];
 | ||
|  |     if (self) {
 | ||
|  |         self.reportingNetworkType = TDReportingNetworkTypeALL;
 | ||
|  |         self.mode = TDModeNormal;
 | ||
|  |         
 | ||
|  |         _trackRelaunchedInBackgroundEvents = NO;
 | ||
|  |         _autoTrackEventType = ThinkingAnalyticsEventTypeNone;
 | ||
|  |         _networkTypePolicy = ThinkingNetworkTypeWIFI | ThinkingNetworkType3G  | ThinkingNetworkType4G | ThinkingNetworkType2G | ThinkingNetworkType5G;
 | ||
|  |         _securityPolicy = [TDSecurityPolicy defaultPolicy];
 | ||
|  |         _defaultTimeZone = [NSTimeZone localTimeZone];
 | ||
|  |     
 | ||
|  | #pragma clang diagnostic push
 | ||
|  | #pragma clang diagnostic ignored "-Wdeprecated-declarations"
 | ||
|  |         if (!configInfo) {
 | ||
|  |             configInfo = (NSDictionary *)[[[NSBundle mainBundle] infoDictionary] objectForKey: kTAConfigInfo];
 | ||
|  |         }
 | ||
|  |         
 | ||
|  |         if (configInfo && [configInfo.allKeys containsObject:@"maxNumEvents"]) {
 | ||
|  |             [TDConfig setMaxNumEvents:[configInfo[@"maxNumEvents"] integerValue]];
 | ||
|  |         }
 | ||
|  |         if (configInfo && [configInfo.allKeys containsObject:@"expirationDays"]) {
 | ||
|  |             [TDConfig setExpirationDays:[configInfo[@"expirationDays"] integerValue]];
 | ||
|  |         }
 | ||
|  | #pragma clang diagnostic pop
 | ||
|  | 
 | ||
|  |     }
 | ||
|  |     return self;
 | ||
|  | }
 | ||
|  | 
 | ||
|  | - (instancetype)initWithAppId:(NSString *)appId serverUrl:(NSString *)serverUrl
 | ||
|  | {
 | ||
|  |     self = [self init];
 | ||
|  |     if (self) {
 | ||
|  |         _appid = appId;
 | ||
|  |         _serverUrl = serverUrl;
 | ||
|  |     }
 | ||
|  |     return self;
 | ||
|  | }
 | ||
|  | 
 | ||
|  | - (void)enableEncryptWithVersion:(NSUInteger)version publicKey:(NSString *)publicKey {
 | ||
|  | #if TARGET_OS_IOS
 | ||
|  |     if ([publicKey isKindOfClass:NSString.class] && publicKey.length > 0) {
 | ||
|  |         self.innerEnableEncrypt = YES;
 | ||
|  |         self.innerSecretKey = [[TDSecretKey alloc] initWithVersion:version publicKey:publicKey];
 | ||
|  |     } else {
 | ||
|  |         self.innerEnableEncrypt = NO;
 | ||
|  |     }
 | ||
|  | #endif
 | ||
|  | }
 | ||
|  | 
 | ||
|  | - (void)enableDNSServcie:(NSArray<TDDNSService> *)services {
 | ||
|  |     // check DNS service list
 | ||
|  |     if (!services || services.count <= 0) {
 | ||
|  |         TDLogDebug(@"Enable DNS service error: Service is empty");
 | ||
|  |         return;
 | ||
|  |     }
 | ||
|  |     NSArray<TDDNSService> *dNSServices = @[TDDNSServiceCloudFlare, TDDNSServiceCloudALi, TDDNSServiceCloudGoogle];
 | ||
|  |     
 | ||
|  |     NSMutableArray *filterServices = [NSMutableArray array];
 | ||
|  |     for (TDDNSService obj in services) {
 | ||
|  |         if ([obj isKindOfClass:NSString.class] && [dNSServices containsObject:obj]) {
 | ||
|  |             [filterServices addObject:obj];
 | ||
|  |         }
 | ||
|  |     }
 | ||
|  |     if (filterServices.count > 0) {
 | ||
|  |         TDLogDebug(@"Enable DNS service. Server url list is: %@", filterServices);
 | ||
|  |         self.dnsServices = filterServices;
 | ||
|  |         [TDAnalyticsNetwork enableDNSServcie:filterServices];
 | ||
|  |     } else {
 | ||
|  |         TDLogDebug(@"Enable DNS service error: Service url authentication failed");
 | ||
|  |     }
 | ||
|  | }
 | ||
|  | 
 | ||
|  | - (void)setName:(NSString *)name {
 | ||
|  |     _name = name.td_trim;
 | ||
|  | }
 | ||
|  | 
 | ||
|  | #pragma mark - NSCopying
 | ||
|  | - (id)copyWithZone:(NSZone *)zone {
 | ||
|  |     TDConfig *config = [[[self class] allocWithZone:zone] init];
 | ||
|  |     config.trackRelaunchedInBackgroundEvents = self.trackRelaunchedInBackgroundEvents;
 | ||
|  |     config.innerNetworkType = self.innerNetworkType;
 | ||
|  |     config.launchOptions = [self.launchOptions copyWithZone:zone];
 | ||
|  |     config.mode = self.mode;
 | ||
|  |     config.reportingNetworkType = self.reportingNetworkType;
 | ||
|  |     config.securityPolicy = [self.securityPolicy copyWithZone:zone];
 | ||
|  |     config.defaultTimeZone = [self.defaultTimeZone copyWithZone:zone];
 | ||
|  |     config.name = [self.name copy];
 | ||
|  |     config.appGroupName = [self.appGroupName copy];
 | ||
|  |     config.serverUrl = [self.serverUrl copy];
 | ||
|  |     config.enableAutoPush = self.enableAutoPush;
 | ||
|  |     config.dnsServices = self.dnsServices;
 | ||
|  | #if TARGET_OS_IOS
 | ||
|  |     config.innerSecretKey = [self.innerSecretKey copyWithZone:zone];
 | ||
|  |     config.innerEnableEncrypt = self.innerEnableEncrypt;
 | ||
|  | #endif
 | ||
|  |     
 | ||
|  |     return config;
 | ||
|  | }
 | ||
|  | 
 | ||
|  | #pragma mark - SETTINGS
 | ||
|  | 
 | ||
|  | - (void)setReportingNetworkType:(TDReportingNetworkType)reportingNetworkType {
 | ||
|  |     switch (reportingNetworkType) {
 | ||
|  |         case TDReportingNetworkTypeWIFI: {
 | ||
|  |             self.innerNetworkType = ThinkingNetworkTypeWIFI;
 | ||
|  |         } break;
 | ||
|  |         case TDReportingNetworkTypeALL: {
 | ||
|  |             self.innerNetworkType = ThinkingNetworkTypeALL;
 | ||
|  |         } break;
 | ||
|  |         default: {
 | ||
|  |             self.innerNetworkType = ThinkingNetworkTypeALL;
 | ||
|  |         } break;
 | ||
|  |     }
 | ||
|  | }
 | ||
|  | 
 | ||
|  | //MARK: - private
 | ||
|  | 
 | ||
|  | - (ThinkingNetworkType)getNetworkType {
 | ||
|  |     return self.innerNetworkType;
 | ||
|  | }
 | ||
|  | 
 | ||
|  | - (void)innerUpdateConfig:(void (^)(NSDictionary *))block {
 | ||
|  |     NSString *serverUrlStr = [NSString stringWithFormat:@"%@/config",self.serverUrl];
 | ||
|  |     TDAnalyticsNetwork *network = [[TDAnalyticsNetwork alloc] init];
 | ||
|  |     network.serverURL = [NSURL URLWithString:serverUrlStr];
 | ||
|  |     network.securityPolicy = _securityPolicy;
 | ||
|  |     
 | ||
|  |     [network fetchRemoteConfig:self.appid handler:^(NSDictionary * _Nonnull result, NSError * _Nullable error) {
 | ||
|  |         if (!error) {
 | ||
|  |             NSInteger uploadInterval = [[result objectForKey:@"sync_interval"] integerValue];
 | ||
|  |             NSInteger uploadSize = [[result objectForKey:@"sync_batch_size"] integerValue];
 | ||
|  |             if (self.enableAutoCalibrated) {
 | ||
|  |                 NSNumber *serverTimestampNum = result[@"server_timestamp"];
 | ||
|  |                 if ([serverTimestampNum isKindOfClass:NSNumber.class]) {
 | ||
|  |                     NSTimeInterval serverTimestamp = [serverTimestampNum doubleValue] * 0.001;
 | ||
|  |                     [[TDCalibratedTime sharedInstance] recalibrationWithTimeInterval:serverTimestamp];
 | ||
|  |                 }
 | ||
|  |             }
 | ||
|  |             if (uploadInterval != [self->_uploadInterval integerValue] || uploadSize != [self->_uploadSize integerValue]) {
 | ||
|  |                 TDFile *file = [[TDFile alloc] initWithAppid:self.appid];
 | ||
|  |                 if (uploadInterval > 0) {
 | ||
|  |                     self.uploadInterval = [NSNumber numberWithInteger:uploadInterval];
 | ||
|  |                     [file archiveUploadInterval:self.uploadInterval];
 | ||
|  |                     NSString *name = self.getInstanceName ? self.getInstanceName() : self.appid;
 | ||
|  |                     [[ThinkingAnalyticsSDK instanceWithAppid:name] startFlushTimer];
 | ||
|  |                 }
 | ||
|  |                 if (uploadSize > 0) {
 | ||
|  |                     self.uploadSize = [NSNumber numberWithInteger:uploadSize];
 | ||
|  |                     [file archiveUploadSize:self.uploadSize];
 | ||
|  |                 }
 | ||
|  |             }
 | ||
|  |             self.disableEvents = [result objectForKey:@"disable_event_list"];
 | ||
|  |             
 | ||
|  |             if (block) {
 | ||
|  |                 block([result objectForKey:@"secret_key"]);
 | ||
|  |             }
 | ||
|  |         }
 | ||
|  |     }];
 | ||
|  | }
 | ||
|  | 
 | ||
|  | - (void)innerUpdateIPMap {
 | ||
|  |     if (self.dnsServices.count <= 0) {
 | ||
|  |         return;
 | ||
|  |     }
 | ||
|  |     NSString *serverUrlStr = [NSString stringWithFormat:@"%@/sync", self.serverUrl];
 | ||
|  |     TDAnalyticsNetwork *network = [[TDAnalyticsNetwork alloc] init];
 | ||
|  |     network.serverURL = [NSURL URLWithString:serverUrlStr];
 | ||
|  |     network.securityPolicy = self.securityPolicy;
 | ||
|  |     [network fetchIPMap];
 | ||
|  | }
 | ||
|  | 
 | ||
|  | - (NSString *)innerGetMapInstanceToken {
 | ||
|  |     if (self.name && [self.name isKindOfClass:[NSString class]] && self.name.length) {
 | ||
|  |         return self.name;
 | ||
|  |     } else {
 | ||
|  |         return self.appid;
 | ||
|  |     }
 | ||
|  | }
 | ||
|  | 
 | ||
|  | //MARK: - Deprecated: public
 | ||
|  | 
 | ||
|  | + (TDConfig *)defaultTDConfig DEPRECATED_MSG_ATTRIBUTE("Deprecated"){
 | ||
|  |     static dispatch_once_t onceToken;
 | ||
|  |     static TDConfig * _defaultTDConfig;
 | ||
|  |     dispatch_once(&onceToken, ^{
 | ||
|  |         _defaultTDConfig = [TDConfig new];
 | ||
|  |     });
 | ||
|  |     return _defaultTDConfig;
 | ||
|  | }
 | ||
|  | 
 | ||
|  | - (NSString *)getMapInstanceToken DEPRECATED_MSG_ATTRIBUTE("Deprecated"){
 | ||
|  |     return [self innerGetMapInstanceToken];
 | ||
|  | }
 | ||
|  | 
 | ||
|  | - (void)updateConfig:(void (^)(NSDictionary *))block DEPRECATED_MSG_ATTRIBUTE("Deprecated"){
 | ||
|  |     [self innerUpdateConfig:block];
 | ||
|  | }
 | ||
|  | 
 | ||
|  | - (void)setNetworkType:(ThinkingAnalyticsNetworkType)type DEPRECATED_MSG_ATTRIBUTE("Deprecated"){
 | ||
|  |     switch (type) {
 | ||
|  |         case TDNetworkTypeOnlyWIFI: {
 | ||
|  |             self.reportingNetworkType = TDReportingNetworkTypeWIFI;
 | ||
|  |         } break;
 | ||
|  |         case TDNetworkTypeALL: {
 | ||
|  |             self.reportingNetworkType = TDReportingNetworkTypeALL;
 | ||
|  |         } break;
 | ||
|  |         default: {
 | ||
|  |             self.innerNetworkType = ThinkingNetworkTypeALL;
 | ||
|  |         } break;
 | ||
|  |     }
 | ||
|  | }
 | ||
|  | 
 | ||
|  | //MARK: - Deprecated: setter & geter
 | ||
|  | 
 | ||
|  | - (void)setConfigureURL:(NSString *)configureURL {
 | ||
|  |     self.serverUrl = configureURL;
 | ||
|  | }
 | ||
|  | 
 | ||
|  | - (NSString *)configureURL {
 | ||
|  |     return self.serverUrl;
 | ||
|  | }
 | ||
|  | 
 | ||
|  | #if TARGET_OS_IOS
 | ||
|  | - (void)setSecretKey:(TDSecretKey *)secretKey {
 | ||
|  |     _secretKey = secretKey;
 | ||
|  |     
 | ||
|  |     [self enableEncryptWithVersion:secretKey.version publicKey:secretKey.publicKey];
 | ||
|  | }
 | ||
|  | 
 | ||
|  | - (void)setEnableEncrypt:(BOOL)enableEncrypt {
 | ||
|  |     _enableEncrypt = enableEncrypt;
 | ||
|  |     self.innerEnableEncrypt = enableEncrypt;
 | ||
|  | }
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | - (void)setNetworkTypePolicy:(ThinkingNetworkType)networkTypePolicy DEPRECATED_MSG_ATTRIBUTE("Deprecated"){
 | ||
|  |     _networkTypePolicy = networkTypePolicy;
 | ||
|  |     self.innerNetworkType = networkTypePolicy;
 | ||
|  | }
 | ||
|  | 
 | ||
|  | - (void)setDebugMode:(ThinkingAnalyticsDebugMode)debugMode DEPRECATED_MSG_ATTRIBUTE("Deprecated"){
 | ||
|  |     _debugMode = debugMode;
 | ||
|  |     self.mode = (TDMode)debugMode;
 | ||
|  | }
 | ||
|  | 
 | ||
|  | + (NSInteger)maxNumEvents DEPRECATED_MSG_ATTRIBUTE("Deprecated"){
 | ||
|  |     NSInteger maxNumEvents = [self _maxNumEventsNumber].integerValue;
 | ||
|  |     if (maxNumEvents < 5000) {
 | ||
|  |         maxNumEvents = 5000;
 | ||
|  |     }
 | ||
|  |     return maxNumEvents;
 | ||
|  | }
 | ||
|  | 
 | ||
|  | + (void)setMaxNumEvents:(NSInteger)maxNumEventsNumber DEPRECATED_MSG_ATTRIBUTE("Deprecated"){
 | ||
|  |     [self _setMaxNumEventsNumber:@(maxNumEventsNumber)];
 | ||
|  | }
 | ||
|  | 
 | ||
|  | + (NSInteger)expirationDays DEPRECATED_MSG_ATTRIBUTE("Deprecated"){
 | ||
|  |     NSInteger maxNumEvents = [self _expirationDaysNumber].integerValue;
 | ||
|  |     return maxNumEvents >= 0 ? maxNumEvents : 10;
 | ||
|  | }
 | ||
|  | 
 | ||
|  | + (void)setExpirationDays:(NSInteger)expirationDays DEPRECATED_MSG_ATTRIBUTE("Deprecated"){
 | ||
|  |     [self _setExpirationDaysNumber:@(expirationDays)];
 | ||
|  | }
 | ||
|  | 
 | ||
|  | @end
 |