Ta android + ios
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
FOUNDATION_EXTERN NSString *const VERSION;
|
||||
|
||||
@interface TDDeviceInfo : NSObject
|
||||
|
||||
+ (TDDeviceInfo *)sharedManager;
|
||||
|
||||
|
||||
@property (nonatomic, copy) NSString *uniqueId;
|
||||
@property (nonatomic, copy) NSString *deviceId;
|
||||
@property (nonatomic, copy) NSString *appVersion;
|
||||
@property (nonatomic, readonly) BOOL isFirstOpen;
|
||||
@property (nonatomic, copy) NSString *libName;
|
||||
@property (nonatomic, copy) NSString *libVersion;
|
||||
|
||||
+ (NSString *)libVersion;
|
||||
+ (NSString*)bundleId;
|
||||
|
||||
- (void)td_updateData;
|
||||
- (NSDictionary *)td_collectProperties;
|
||||
|
||||
+ (NSDate *)td_getInstallTime;
|
||||
|
||||
- (NSDictionary *)getAutomaticData;
|
||||
|
||||
+ (NSString *)currentRadio;
|
||||
|
||||
+ (NSTimeInterval)uptime;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a60930b943f31e4b9e33f854dd218c7
|
||||
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,481 @@
|
||||
#import "TDDeviceInfo.h"
|
||||
#import <CoreTelephony/CTCarrier.h>
|
||||
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
|
||||
#import <sys/utsname.h>
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
#import <UIKit/UIKit.h>
|
||||
#elif TARGET_OS_OSX
|
||||
#import <AppKit/AppKit.h>
|
||||
#endif
|
||||
|
||||
#import "TDKeychainHelper.h"
|
||||
#import "TDPublicConfig.h"
|
||||
#import "ThinkingAnalyticsSDKPrivate.h"
|
||||
#import "TDFile.h"
|
||||
#import "TDPresetProperties+TDDisProperties.h"
|
||||
#import <sys/sysctl.h>
|
||||
|
||||
#define kTDDyldPropertyNames @[@"TDPerformance"]
|
||||
#define kTDGetPropertySelName @"getPresetProperties"
|
||||
|
||||
#define kDeviceClass @"XY2HU4AX3JI2JJW5MDhjm6wea2x6ymvm28ylmiyh7jkc8axy9mw3em8w"
|
||||
#define kCurrentDevice @"0a223h444j555cm666uw77722rh985jrj323ae44y5xn5ll5tm5mD5wm6e8y9m0vm32y46i7a89x0yl32c44ml4ye5a3a5"
|
||||
#define kIdfv @"hj23kik4343j545dk656ke43434hhn534536jj7676tx323423yyx547657iy7678yxf7654hhl32342im3424ww4235w546ew64645w76ll57rx67yF434hj323ao343aa546rk76l323Vx32y32y32x32e3m43w656m76nxy657k657lmd65y657yx5o323aa34kk45rk76k76lm87"
|
||||
#define kUUIDStr @"323J342J342K342U657K675A87A87U879H0943AX908IJ214KWD54WW87SX98XY3425At769k93l2l548m7r32xyx76769im3234ww6576n8ax89g98k9l97m1w31242"
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
static CTTelephonyNetworkInfo *__td_TelephonyNetworkInfo;
|
||||
#endif
|
||||
|
||||
@interface TDDeviceInfo ()
|
||||
|
||||
@property (nonatomic, readwrite) BOOL isFirstOpen;
|
||||
@property (atomic, strong) NSDictionary *automaticData;
|
||||
|
||||
@end
|
||||
|
||||
@implementation TDDeviceInfo
|
||||
|
||||
+ (void)load {
|
||||
#if TARGET_OS_IOS
|
||||
__td_TelephonyNetworkInfo = [[CTTelephonyNetworkInfo alloc] init];
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+ (TDDeviceInfo *)sharedManager {
|
||||
static dispatch_once_t onceToken;
|
||||
static TDDeviceInfo *manager;
|
||||
dispatch_once(&onceToken, ^{
|
||||
manager = [[TDDeviceInfo alloc] init];
|
||||
});
|
||||
return manager;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.libName = @"iOS";
|
||||
self.libVersion = TDPublicConfig.version;
|
||||
|
||||
NSDictionary *deviceInfo = [self getDeviceUniqueId];
|
||||
_uniqueId = [deviceInfo objectForKey:@"uniqueId"];
|
||||
_deviceId = [deviceInfo objectForKey:@"deviceId"];
|
||||
_appVersion = [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"];
|
||||
|
||||
self.automaticData = [self td_collectProperties];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (NSString *)libVersion {
|
||||
return [self sharedManager].libVersion;
|
||||
}
|
||||
|
||||
- (void)td_updateData {
|
||||
self.automaticData = [self td_collectProperties];
|
||||
}
|
||||
|
||||
-(NSDictionary *)getAutomaticData {
|
||||
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:self.automaticData];
|
||||
[dic addEntriesFromDictionary:[TDDeviceInfo getAPMParams]];
|
||||
self.automaticData = dic;
|
||||
return self.automaticData;
|
||||
}
|
||||
|
||||
- (NSDictionary *)td_collectProperties {
|
||||
NSMutableDictionary *p = [NSMutableDictionary dictionary];
|
||||
|
||||
if (![TDPresetProperties disableDeviceId]) {
|
||||
[p setValue:_deviceId forKey:@"#device_id"];
|
||||
}
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
if (![TDPresetProperties disableCarrier]) {
|
||||
CTCarrier *carrier = nil;
|
||||
NSString *carrierName = @"";
|
||||
#ifdef __IPHONE_12_0
|
||||
if (@available(iOS 12.1, *)) {
|
||||
NSArray *carrierKeysArray = [__td_TelephonyNetworkInfo.serviceSubscriberCellularProviders.allKeys sortedArrayUsingSelector:@selector(compare:)];
|
||||
carrier = __td_TelephonyNetworkInfo.serviceSubscriberCellularProviders[carrierKeysArray.firstObject];
|
||||
if (!carrier.mobileNetworkCode) {
|
||||
carrier = __td_TelephonyNetworkInfo.serviceSubscriberCellularProviders[carrierKeysArray.lastObject];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!carrier) {
|
||||
carrier = [__td_TelephonyNetworkInfo subscriberCellularProvider];
|
||||
}
|
||||
|
||||
// System characteristics, when the SIM is not installed, the carrierName also has a value, here additionally add the judgment of whether MCC and MNC have values
|
||||
// MCC, MNC, and isoCountryCode are nil when no SIM card is installed and not within the cellular service range
|
||||
if (carrier.carrierName &&
|
||||
carrier.carrierName.length > 0 &&
|
||||
carrier.mobileNetworkCode &&
|
||||
carrier.mobileNetworkCode.length > 0) {
|
||||
carrierName = carrier.carrierName;
|
||||
}
|
||||
[p setValue:carrierName forKey:@"#carrier"];
|
||||
}
|
||||
#endif
|
||||
|
||||
if (![TDPresetProperties disableLibVersion]) {
|
||||
[p setValue:self.libVersion forKey:@"#lib_version"];
|
||||
}
|
||||
if (![TDPresetProperties disableManufacturer]) {
|
||||
[p setValue:@"Apple" forKey:@"#manufacturer"];
|
||||
}
|
||||
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
if (![TDPresetProperties disableDeviceModel]) {
|
||||
[p setValue:[self td_iphoneType] forKey:@"#device_model"];
|
||||
}
|
||||
|
||||
if (![TDPresetProperties disableLib]) {
|
||||
[p setValue:self.libName forKey:@"#lib"];
|
||||
}
|
||||
|
||||
if (![TDPresetProperties disableOs]) {
|
||||
[p setValue:@"iOS" forKey:@"#os"];
|
||||
}
|
||||
if (![TDPresetProperties disableOsVersion]) {
|
||||
UIDevice *device = [UIDevice currentDevice];
|
||||
[p setValue:[device systemVersion] forKey:@"#os_version"];
|
||||
}
|
||||
if (![TDPresetProperties disableScreenWidth]) {
|
||||
CGSize size = [UIScreen mainScreen].bounds.size;
|
||||
[p setValue:@((NSInteger)size.width) forKey:@"#screen_width"];
|
||||
}
|
||||
if (![TDPresetProperties disableScreenHeight]) {
|
||||
CGSize size = [UIScreen mainScreen].bounds.size;
|
||||
[p setValue:@((NSInteger)size.height) forKey:@"#screen_height"];
|
||||
}
|
||||
|
||||
if (![TDPresetProperties disableDeviceType]) {
|
||||
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
|
||||
[p setValue:@"iPad" forKey:@"#device_type"];
|
||||
} else {
|
||||
[p setValue:@"iPhone" forKey:@"#device_type"];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_OSX
|
||||
|
||||
if (![TDPresetProperties disableLib]) {
|
||||
[p setValue:@"Mac OS" forKey:@"#lib"];
|
||||
}
|
||||
|
||||
if (![TDPresetProperties disableOs]) {
|
||||
[p setValue:@"OSX" forKey:@"#os"];
|
||||
}
|
||||
if (![TDPresetProperties disableOsVersion]) {
|
||||
NSDictionary *sv = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"];
|
||||
NSString *versionString = [sv objectForKey:@"ProductVersion"];
|
||||
[p setValue:versionString forKey:@"#os_version"];
|
||||
}
|
||||
#endif
|
||||
if (![TDPresetProperties disableSystemLanguage]) {
|
||||
NSString *preferredLanguages = [[NSLocale preferredLanguages] firstObject];
|
||||
if (preferredLanguages && preferredLanguages.length > 0) {
|
||||
p[@"#system_language"] = [[preferredLanguages componentsSeparatedByString:@"-"] firstObject];;
|
||||
}
|
||||
}
|
||||
[p addEntriesFromDictionary:[TDDeviceInfo getAPMParams]];
|
||||
|
||||
return [p copy];
|
||||
}
|
||||
|
||||
+ (NSString*)bundleId
|
||||
{
|
||||
return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
|
||||
}
|
||||
|
||||
- (NSString *)td_iphoneType {
|
||||
struct utsname systemInfo;
|
||||
uname(&systemInfo);
|
||||
NSString *platform = [NSString stringWithCString:systemInfo.machine encoding:NSASCIIStringEncoding];
|
||||
if ([platform isEqualToString:@"iPhone1,1"]) return @"iPhone 2G";
|
||||
if ([platform isEqualToString:@"iPhone1,2"]) return @"iPhone 3G";
|
||||
if ([platform isEqualToString:@"iPhone2,1"]) return @"iPhone 3GS";
|
||||
if ([platform isEqualToString:@"iPhone3,1"]) return @"iPhone 4";
|
||||
if ([platform isEqualToString:@"iPhone3,2"]) return @"iPhone 4";
|
||||
if ([platform isEqualToString:@"iPhone3,3"]) return @"iPhone 4";
|
||||
if ([platform isEqualToString:@"iPhone4,1"]) return @"iPhone 4S";
|
||||
if ([platform isEqualToString:@"iPhone5,1"]) return @"iPhone 5";
|
||||
if ([platform isEqualToString:@"iPhone5,2"]) return @"iPhone 5";
|
||||
if ([platform isEqualToString:@"iPhone5,3"]) return @"iPhone 5c";
|
||||
if ([platform isEqualToString:@"iPhone5,4"]) return @"iPhone 5c";
|
||||
if ([platform isEqualToString:@"iPhone6,1"]) return @"iPhone 5s";
|
||||
if ([platform isEqualToString:@"iPhone6,2"]) return @"iPhone 5s";
|
||||
if ([platform isEqualToString:@"iPhone7,1"]) return @"iPhone 6 Plus";
|
||||
if ([platform isEqualToString:@"iPhone7,2"]) return @"iPhone 6";
|
||||
if ([platform isEqualToString:@"iPhone8,1"]) return @"iPhone 6s";
|
||||
if ([platform isEqualToString:@"iPhone8,2"]) return @"iPhone 6s Plus";
|
||||
if ([platform isEqualToString:@"iPhone8,4"]) return @"iPhone SE";
|
||||
if ([platform isEqualToString:@"iPhone9,1"]) return @"iPhone 7";
|
||||
if ([platform isEqualToString:@"iPhone9,2"]) return @"iPhone 7 Plus";
|
||||
if ([platform isEqualToString:@"iPod1,1"]) return @"iPod Touch 1G";
|
||||
if ([platform isEqualToString:@"iPod2,1"]) return @"iPod Touch 2G";
|
||||
if ([platform isEqualToString:@"iPod3,1"]) return @"iPod Touch 3G";
|
||||
if ([platform isEqualToString:@"iPod4,1"]) return @"iPod Touch 4G";
|
||||
if ([platform isEqualToString:@"iPod5,1"]) return @"iPod Touch 5G";
|
||||
if ([platform isEqualToString:@"iPad1,1"]) return @"iPad 1G";
|
||||
if ([platform isEqualToString:@"iPad2,1"]) return @"iPad 2";
|
||||
if ([platform isEqualToString:@"iPad2,2"]) return @"iPad 2";
|
||||
if ([platform isEqualToString:@"iPad2,3"]) return @"iPad 2";
|
||||
if ([platform isEqualToString:@"iPad2,4"]) return @"iPad 2";
|
||||
if ([platform isEqualToString:@"iPad2,5"]) return @"iPad Mini 1G";
|
||||
if ([platform isEqualToString:@"iPad2,6"]) return @"iPad Mini 1G";
|
||||
if ([platform isEqualToString:@"iPad2,7"]) return @"iPad Mini 1G";
|
||||
if ([platform isEqualToString:@"iPad3,1"]) return @"iPad 3";
|
||||
if ([platform isEqualToString:@"iPad3,2"]) return @"iPad 3";
|
||||
if ([platform isEqualToString:@"iPad3,3"]) return @"iPad 3";
|
||||
if ([platform isEqualToString:@"iPad3,4"]) return @"iPad 4";
|
||||
if ([platform isEqualToString:@"iPad3,5"]) return @"iPad 4";
|
||||
if ([platform isEqualToString:@"iPad3,6"]) return @"iPad 4";
|
||||
if ([platform isEqualToString:@"iPad4,1"]) return @"iPad Air";
|
||||
if ([platform isEqualToString:@"iPad4,2"]) return @"iPad Air";
|
||||
if ([platform isEqualToString:@"iPad4,3"]) return @"iPad Air";
|
||||
if ([platform isEqualToString:@"iPad4,4"]) return @"iPad Mini 2G";
|
||||
if ([platform isEqualToString:@"iPad4,5"]) return @"iPad Mini 2G";
|
||||
if ([platform isEqualToString:@"iPad4,6"]) return @"iPad Mini 2G";
|
||||
if ([platform isEqualToString:@"i386"]) return @"iPhone Simulator";
|
||||
if ([platform isEqualToString:@"x86_64"]) return @"iPhone Simulator";
|
||||
return platform;
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (NSDictionary *)getDeviceUniqueId {
|
||||
|
||||
NSString *defaultDistinctId = [self getIdentifier];
|
||||
NSString *deviceId;
|
||||
NSString *uniqueId;
|
||||
|
||||
TDKeychainHelper *wrapper = [[TDKeychainHelper alloc] init];
|
||||
NSString *deviceIdKeychain = [wrapper readDeviceId];
|
||||
NSString *installTimesKeychain = [wrapper readInstallTimes];
|
||||
|
||||
BOOL isExistFirstRecord = [[[NSUserDefaults standardUserDefaults] objectForKey:@"thinking_isfirst"] boolValue];
|
||||
if (!isExistFirstRecord) {
|
||||
_isFirstOpen = YES;
|
||||
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"thinking_isfirst"];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
} else {
|
||||
_isFirstOpen = NO;
|
||||
}
|
||||
|
||||
if (deviceIdKeychain.length == 0 || installTimesKeychain.length == 0) {
|
||||
[wrapper readOldKeychain];
|
||||
deviceIdKeychain = [wrapper getDeviceIdOld];
|
||||
installTimesKeychain = [wrapper getInstallTimesOld];
|
||||
}
|
||||
|
||||
TDFile *file = [[TDFile alloc] initWithAppid:[ThinkingAnalyticsSDK sharedInstance].appid];
|
||||
if (deviceIdKeychain.length == 0 || installTimesKeychain.length == 0) {
|
||||
deviceIdKeychain = [file unarchiveDeviceId];
|
||||
installTimesKeychain = [file unarchiveInstallTimes];
|
||||
}
|
||||
|
||||
if (deviceIdKeychain.length == 0 || installTimesKeychain.length == 0) {
|
||||
deviceId = defaultDistinctId;
|
||||
installTimesKeychain = @"1";
|
||||
} else {
|
||||
if (!isExistFirstRecord) {
|
||||
int setup_int = [installTimesKeychain intValue];
|
||||
setup_int++;
|
||||
|
||||
installTimesKeychain = [NSString stringWithFormat:@"%d",setup_int];
|
||||
}
|
||||
|
||||
deviceId = deviceIdKeychain;
|
||||
}
|
||||
|
||||
if ([installTimesKeychain isEqualToString:@"1"]) {
|
||||
uniqueId = deviceId;
|
||||
} else {
|
||||
uniqueId = [NSString stringWithFormat:@"%@_%@",deviceId,installTimesKeychain];
|
||||
}
|
||||
|
||||
[wrapper saveDeviceId:deviceId];
|
||||
[wrapper saveInstallTimes:installTimesKeychain];
|
||||
[file archiveDeviceId:deviceId];
|
||||
[file archiveInstallTimes:installTimesKeychain];
|
||||
return @{@"uniqueId":uniqueId, @"deviceId":deviceId};
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
|
||||
|
||||
- (NSString *)getIdentifier {
|
||||
NSString *anonymityId = NULL;
|
||||
|
||||
Class deviceCls = NSClassFromString([self dealStringWithRegExp:kDeviceClass]);
|
||||
if (deviceCls) {
|
||||
SEL currentDve = NSSelectorFromString([self dealStringWithRegExp:kCurrentDevice]);
|
||||
SEL idfvor = NSSelectorFromString([self dealStringWithRegExp:kIdfv]);
|
||||
SEL uuidStr = NSSelectorFromString([self dealStringWithRegExp:kUUIDStr]);
|
||||
|
||||
if ([deviceCls respondsToSelector:currentDve]) {
|
||||
id cls1 = [deviceCls performSelector:currentDve];
|
||||
if (cls1 && [cls1 respondsToSelector:idfvor]) {
|
||||
id cls2 = [cls1 performSelector:idfvor];
|
||||
if (cls2 && [cls2 respondsToSelector:uuidStr]) {
|
||||
id tempAnonymityId = [cls2 performSelector:uuidStr];
|
||||
if ([tempAnonymityId isKindOfClass:[NSString class]]) {
|
||||
anonymityId = tempAnonymityId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!anonymityId) {
|
||||
anonymityId = [[NSUUID UUID] UUIDString];
|
||||
}
|
||||
|
||||
return anonymityId;
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
|
||||
- (NSString *)dealStringWithRegExp:(NSString *)string {
|
||||
NSRegularExpression *regExp = [[NSRegularExpression alloc]initWithPattern:@"[0-9AXYHJKLMW]"
|
||||
options:NSRegularExpressionCaseInsensitive
|
||||
error:nil];
|
||||
return [regExp stringByReplacingMatchesInString:string
|
||||
options:NSMatchingReportProgress
|
||||
range:NSMakeRange(0, string.length)
|
||||
withTemplate:@""];
|
||||
}
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
|
||||
+ (NSString *)currentRadio {
|
||||
NSString *networkType = @"NULL";
|
||||
|
||||
if (!__td_TelephonyNetworkInfo) {
|
||||
return networkType;
|
||||
}
|
||||
|
||||
@try {
|
||||
NSString *currentRadio = nil;
|
||||
|
||||
#ifdef __IPHONE_12_0
|
||||
if (@available(iOS 12.0, *)) {
|
||||
NSDictionary *serviceCurrentRadio = [__td_TelephonyNetworkInfo serviceCurrentRadioAccessTechnology];
|
||||
if ([serviceCurrentRadio isKindOfClass:[NSDictionary class]] && serviceCurrentRadio.allValues.count>0) {
|
||||
currentRadio = serviceCurrentRadio.allValues[0];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (currentRadio == nil && [__td_TelephonyNetworkInfo.currentRadioAccessTechnology isKindOfClass:[NSString class]]) {
|
||||
currentRadio = __td_TelephonyNetworkInfo.currentRadioAccessTechnology;
|
||||
}
|
||||
|
||||
if ([currentRadio isEqualToString:CTRadioAccessTechnologyLTE]) {
|
||||
networkType = @"4G";
|
||||
} else if ([currentRadio isEqualToString:CTRadioAccessTechnologyeHRPD] ||
|
||||
[currentRadio isEqualToString:CTRadioAccessTechnologyCDMAEVDORevB] ||
|
||||
[currentRadio isEqualToString:CTRadioAccessTechnologyCDMAEVDORevA] ||
|
||||
[currentRadio isEqualToString:CTRadioAccessTechnologyCDMAEVDORev0] ||
|
||||
[currentRadio isEqualToString:CTRadioAccessTechnologyCDMA1x] ||
|
||||
[currentRadio isEqualToString:CTRadioAccessTechnologyHSUPA] ||
|
||||
[currentRadio isEqualToString:CTRadioAccessTechnologyHSDPA] ||
|
||||
[currentRadio isEqualToString:CTRadioAccessTechnologyWCDMA]) {
|
||||
networkType = @"3G";
|
||||
} else if ([currentRadio isEqualToString:CTRadioAccessTechnologyEdge] ||
|
||||
[currentRadio isEqualToString:CTRadioAccessTechnologyGPRS]) {
|
||||
networkType = @"2G";
|
||||
}
|
||||
#ifdef __IPHONE_14_1
|
||||
else if (@available(iOS 14.1, *)) {
|
||||
if ([currentRadio isKindOfClass:[NSString class]]) {
|
||||
if([currentRadio isEqualToString:CTRadioAccessTechnologyNRNSA] ||
|
||||
[currentRadio isEqualToString:CTRadioAccessTechnologyNR]) {
|
||||
networkType = @"5G";
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} @catch (NSException *exception) {
|
||||
TDLogError(@"%@: %@", self, exception);
|
||||
}
|
||||
|
||||
return networkType;
|
||||
}
|
||||
|
||||
#elif TARGET_OS_OSX
|
||||
+ (NSString *)currentRadio {
|
||||
return @"WIFI";
|
||||
}
|
||||
#endif
|
||||
|
||||
+ (NSDate *)td_getInstallTime {
|
||||
|
||||
NSURL* urlToDocumentsFolder = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
|
||||
__autoreleasing NSError *error;
|
||||
NSDate *installDate = [[[NSFileManager defaultManager] attributesOfItemAtPath:urlToDocumentsFolder.path error:&error] objectForKey:NSFileCreationDate];
|
||||
if (!error) {
|
||||
return installDate;
|
||||
}
|
||||
return [NSDate date];
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
|
||||
|
||||
+ (NSDictionary *)getAPMParams {
|
||||
NSMutableDictionary *p = [NSMutableDictionary dictionary];
|
||||
for (NSString *clsName in kTDDyldPropertyNames) {
|
||||
Class cls = NSClassFromString(clsName);
|
||||
SEL sel = NSSelectorFromString(kTDGetPropertySelName);
|
||||
if (cls && sel && [cls respondsToSelector:sel]) {
|
||||
NSDictionary *result = [cls performSelector:sel];
|
||||
// NSDictionary *result = [NSObject performSelector:sel onTarget:cls withArguments:@[]];
|
||||
if ([result isKindOfClass:[NSDictionary class]] && result.allKeys.count > 0) {
|
||||
[p addEntriesFromDictionary:result];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
+ (BOOL)isIPad {
|
||||
#if TARGET_OS_IOS
|
||||
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
|
||||
#elif TARGET_OS_OSX
|
||||
return NO;
|
||||
#endif
|
||||
}
|
||||
|
||||
+ (NSTimeInterval)uptime
|
||||
{
|
||||
struct timeval boottime;
|
||||
int mib[2] = {CTL_KERN, KERN_BOOTTIME};
|
||||
size_t size = sizeof(boottime);
|
||||
|
||||
struct timeval now;
|
||||
struct timezone tz;
|
||||
gettimeofday(&now, &tz);
|
||||
|
||||
double uptime = -1;
|
||||
|
||||
if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 && boottime.tv_sec != 0)
|
||||
{
|
||||
uptime = now.tv_sec - boottime.tv_sec;
|
||||
uptime += (double)(now.tv_usec - boottime.tv_usec) / 1000000.0;
|
||||
}
|
||||
return uptime;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01250d16ad3f65c41908ee8941191529
|
||||
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 @@
|
||||
//
|
||||
// TDFPSMonitor.h
|
||||
// SSAPMSDK
|
||||
//
|
||||
// Created by wwango on 2021/9/7.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TDFPSMonitor : NSObject
|
||||
|
||||
@property (nonatomic, assign, getter=isEnable) BOOL enable;
|
||||
|
||||
- (NSNumber *)getPFS;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4fc3ed786525c3f4597a19ade7f43499
|
||||
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,76 @@
|
||||
//
|
||||
// TDFPSMonitor.m
|
||||
// SSAPMSDK
|
||||
//
|
||||
// Created by wwango on 2021/9/7.
|
||||
//
|
||||
|
||||
#import "TDFPSMonitor.h"
|
||||
#import <QuartzCore/CADisplayLink.h>
|
||||
#import "TDWeakProxy.h"
|
||||
|
||||
@interface TDFPSMonitor () {
|
||||
CADisplayLink *_link;
|
||||
NSUInteger _count;
|
||||
NSTimeInterval _lastTime;
|
||||
int _thinkingdata_fps;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation TDFPSMonitor
|
||||
|
||||
- (void)setEnable:(BOOL)enable {
|
||||
_enable = enable;
|
||||
if (_enable) {
|
||||
[self startDisplay];
|
||||
} else {
|
||||
[self stopDisplay];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSNumber *)getPFS {
|
||||
return [NSNumber numberWithInt:[NSString stringWithFormat:@"%d", _thinkingdata_fps].intValue];
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
if (_link) {
|
||||
[_link invalidate];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)startDisplay {
|
||||
|
||||
if (_link) return;
|
||||
|
||||
_thinkingdata_fps = 60;
|
||||
_link = [CADisplayLink displayLinkWithTarget:[TDWeakProxy proxyWithTarget:self] selector:@selector(tick:)];
|
||||
// _link.preferredFrameRateRange = CAFrameRateRangeMake(60, 120, 120);
|
||||
[_link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
|
||||
}
|
||||
|
||||
- (void)stopDisplay {
|
||||
if (_link) {
|
||||
[_link invalidate];
|
||||
_link= nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)tick:(CADisplayLink *)link {
|
||||
if (_lastTime == 0) {
|
||||
_lastTime = link.timestamp;
|
||||
return;
|
||||
}
|
||||
|
||||
_count++;
|
||||
NSTimeInterval delta = link.timestamp - _lastTime;
|
||||
if (delta < 1.0) return;
|
||||
_lastTime = link.timestamp;
|
||||
_thinkingdata_fps = _count / delta;
|
||||
_count = 0;
|
||||
|
||||
// NSLog(@"@@@@@FPS:%i", _thinkingdata_fps);
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aa4fa74cbdebf634ca82ffea792698ea
|
||||
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 @@
|
||||
//
|
||||
// TDPerformance.h
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by wwango on 2021/12/23.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TDPerformance : NSObject
|
||||
|
||||
@end
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fd598319e2151f847a2b2a281e15e0e1
|
||||
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,176 @@
|
||||
//
|
||||
// TDPerformance.m
|
||||
// ThinkingSDK
|
||||
//
|
||||
// Created by wwango on 2021/12/23.
|
||||
//
|
||||
|
||||
#import "TDPerformance.h"
|
||||
#import "TDFPSMonitor.h"
|
||||
#include <mach/mach.h>
|
||||
#include <malloc/malloc.h>
|
||||
#import <sys/sysctl.h>
|
||||
#include <mach-o/arch.h>
|
||||
#import <objc/message.h>
|
||||
#import "TDPresetProperties+TDDisProperties.h"
|
||||
|
||||
typedef TDPresetProperties TDAPMPresetProperty;
|
||||
|
||||
static const NSString *kTDPerformanceRAM = @"#ram";
|
||||
static const NSString *kTDPerformanceDISK = @"#disk";
|
||||
static const NSString *kTDPerformanceSIM = @"#simulator";
|
||||
static const NSString *kTDPerformanceFPS = @"#fps";
|
||||
|
||||
#define TD_MAIM_INFO_PLIST_DISPRESTPRO_KEY @"TDDisPresetProperties"
|
||||
|
||||
#define TD_PM_UNIT_KB 1024.0
|
||||
#define TD_PM_UNIT_MB (1024.0 * TD_PM_UNIT_KB)
|
||||
#define TD_PM_UNIT_GB (1024.0 * TD_PM_UNIT_MB)
|
||||
|
||||
TDFPSMonitor *fpsMonitor;
|
||||
|
||||
@implementation TDPerformance
|
||||
|
||||
+ (NSDictionary *)getPresetProperties {
|
||||
|
||||
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
|
||||
|
||||
if (![TDAPMPresetProperty disableRAM]) {
|
||||
NSString *ram = [NSString stringWithFormat:@"%.1f/%.1f",
|
||||
[TDPerformance td_pm_func_getFreeMemory]*1.0/TD_PM_UNIT_GB,
|
||||
[TDPerformance td_pm_func_getRamSize]*1.0/TD_PM_UNIT_GB];
|
||||
if (ram && ram.length) {
|
||||
[dic setObject:ram forKey:kTDPerformanceRAM];
|
||||
}
|
||||
}
|
||||
|
||||
if (![TDAPMPresetProperty disableDisk]) {
|
||||
NSString *disk = [NSString stringWithFormat:@"%.1f/%.1f",
|
||||
[TDPerformance td_get_disk_free_size]*1.0/TD_PM_UNIT_GB,
|
||||
[TDPerformance td_get_storage_size]*1.0/TD_PM_UNIT_GB];
|
||||
if (disk && disk.length) {
|
||||
[dic setObject:disk forKey:kTDPerformanceDISK];
|
||||
}
|
||||
}
|
||||
|
||||
if (![TDAPMPresetProperty disableSimulator]) {
|
||||
|
||||
#ifdef TARGET_OS_IPHONE
|
||||
#if TARGET_IPHONE_SIMULATOR
|
||||
[dic setObject:@(YES) forKey:kTDPerformanceSIM];
|
||||
#elif TARGET_OS_SIMULATOR
|
||||
[dic setObject:@(YES) forKey:kTDPerformanceSIM];
|
||||
#else
|
||||
[dic setObject:@(NO) forKey:kTDPerformanceSIM];
|
||||
#endif
|
||||
#else
|
||||
[dic setObject:@(YES) forKey:kTDPerformanceSIM];
|
||||
#endif
|
||||
}
|
||||
|
||||
if (![TDAPMPresetProperty disableFPS]) {
|
||||
if (!fpsMonitor) {
|
||||
fpsMonitor = [[TDFPSMonitor alloc] init];
|
||||
[fpsMonitor setEnable:YES];
|
||||
[dic setObject:[fpsMonitor getPFS] forKey:kTDPerformanceFPS];
|
||||
} else {
|
||||
[dic setObject:[fpsMonitor getPFS] forKey:kTDPerformanceFPS];
|
||||
}
|
||||
}
|
||||
return dic;
|
||||
}
|
||||
|
||||
#pragma mark - memory
|
||||
|
||||
+ (int64_t)td_pm_func_getFreeMemory {
|
||||
size_t length = 0;
|
||||
int mib[6] = {0};
|
||||
|
||||
int pagesize = 0;
|
||||
mib[0] = CTL_HW;
|
||||
mib[1] = HW_PAGESIZE;
|
||||
length = sizeof(pagesize);
|
||||
if (sysctl(mib, 2, &pagesize, &length, NULL, 0) < 0){
|
||||
return -1;
|
||||
}
|
||||
mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
|
||||
vm_statistics_data_t vmstat;
|
||||
if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmstat, &count) != KERN_SUCCESS){
|
||||
return -1;
|
||||
}
|
||||
|
||||
int64_t freeMem = vmstat.free_count * pagesize;
|
||||
int64_t inactiveMem = vmstat.inactive_count * pagesize;
|
||||
return freeMem + inactiveMem;
|
||||
}
|
||||
|
||||
+ (int64_t)td_pm_func_getRamSize{
|
||||
int mib[2];
|
||||
size_t length = 0;
|
||||
|
||||
mib[0] = CTL_HW;
|
||||
mib[1] = HW_MEMSIZE;
|
||||
long ram;
|
||||
length = sizeof(ram);
|
||||
if (sysctl(mib, 2, &ram, &length, NULL, 0) < 0) {
|
||||
return -1;
|
||||
}
|
||||
return ram;
|
||||
}
|
||||
|
||||
#pragma mark - disk
|
||||
|
||||
+ (NSDictionary *)td_pm_getFileAttributeDic {
|
||||
NSError *error;
|
||||
NSDictionary *directory = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:&error];
|
||||
if (error) {
|
||||
return nil;
|
||||
}
|
||||
return directory;
|
||||
}
|
||||
|
||||
+ (long long)td_get_disk_free_size {
|
||||
NSDictionary<NSFileAttributeKey, id> *directory = [self td_pm_getFileAttributeDic];
|
||||
if (directory) {
|
||||
return [[directory objectForKey:NSFileSystemFreeSize] unsignedLongLongValue];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ (long long)td_get_storage_size {
|
||||
NSDictionary<NSFileAttributeKey, id> *directory = [self td_pm_getFileAttributeDic];
|
||||
return directory ? ((NSNumber *)[directory objectForKey:NSFileSystemSize]).unsignedLongLongValue:-1;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation TDPerformance (PresetProperty)
|
||||
|
||||
+ (NSArray*)disPerformancePresetProperties {
|
||||
static NSArray *arr;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
arr = (NSArray *)[[[NSBundle mainBundle] infoDictionary] objectForKey:TD_MAIM_INFO_PLIST_DISPRESTPRO_KEY];
|
||||
});
|
||||
return arr;
|
||||
}
|
||||
|
||||
+ (BOOL)needFPS {
|
||||
return ![[self disPerformancePresetProperties] containsObject:kTDPerformanceFPS];
|
||||
}
|
||||
|
||||
+ (BOOL)needRAM {
|
||||
return ![[self disPerformancePresetProperties] containsObject:kTDPerformanceRAM];
|
||||
}
|
||||
|
||||
+ (BOOL)needDisk {
|
||||
return ![[self disPerformancePresetProperties] containsObject:kTDPerformanceDISK];
|
||||
}
|
||||
|
||||
+ (BOOL)needSimulator {
|
||||
return ![[self disPerformancePresetProperties] containsObject:kTDPerformanceSIM];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84a08b6191b46604faa7ded801773034
|
||||
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