// // DataController.m // CParam // // Created by breeze on 2017/6/20. // Copyright © 2017年 Breeze. All rights reserved. // #import "DataController.h" #import "IdentityData.h" #include #include #include #include #import "SSKeychain.h" #import #import #import #import #define kAppGIDFile @"appGID.dat" #define kServerIDFile @"appSID.dat" #define kDeviceUIDFile @"deviceUID.dat" #define kAppUIDFile @"appUID.dat" // 全局数据控制器 static DataController *globalDataController = nil; @implementation DataController { IdentityData *identityData; // 身份数据 } // 获取数据管理的控制器 + (DataController *)getInstance { @synchronized(self) { // 实例对象只分配一次 if(globalDataController == nil) { globalDataController = [[super allocWithZone:NULL] init]; } } return globalDataController; } + (id)allocWithZone:(NSZone *)zone { return [self getInstance]; } - (id)copyWithZone:(NSZone *)zone { return self; } // 初始化 - (void)initIdentityData { if(identityData == nil) { identityData = [[IdentityData alloc] init]; } } + (NSString*)getAppGroupID { //获取Bundle identifier NSDictionary *dic = [[NSBundle mainBundle] infoDictionary]; NSString *appName = [dic objectForKey:@"CFBundleIdentifier"]; // 查找第一个点 NSRange range = [appName rangeOfString:@"."]; // 取第一个点及后面的内容 NSString* subString = [appName substringWithRange:NSMakeRange(range.location, [appName length]-range.location)]; // 连接字符串 NSString* appGroupName = [@"group" stringByAppendingString:subString]; return appGroupName; } #pragma mark - 获取和设置程序用户ID // =================================================================== // 获取和设置程序用户ID // =================================================================== // 获取程序用户ID - (NSString *)appGID { [self initIdentityData]; // 如果没有加载 if([identityData appGID] == nil) { // 获取document文件夹位置 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentDirectory = [paths objectAtIndex:0]; // 加载GID文件 NSString *appGIDPath = [documentDirectory stringByAppendingPathComponent: kAppGIDFile]; // 该文件存在 if([[NSFileManager defaultManager] fileExistsAtPath:appGIDPath]) { NSString *appIDFromFile = [[NSString alloc] initWithContentsOfFile:appGIDPath encoding:NSUTF8StringEncoding error:nil]; [self setAppGID:appIDFromFile]; } // 该文件不存在,设置成默认值(空字符串) else { [self setAppGID:@""]; } } return [identityData appGID]; } // 设置程序用户ID - (void)setAppGID:(NSString *)appGIDNew { [self initIdentityData]; [identityData setAppGID:appGIDNew]; } // 获取程序用户UID - (NSString *)appUID { [self initIdentityData]; // 如果没有加载 if([identityData appUID] == nil) { // 获取document文件夹位置 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentDirectory = [paths objectAtIndex:0]; // 加载UID文件 NSString *appUIDPath = [documentDirectory stringByAppendingPathComponent:kAppUIDFile]; //获取sandbox的UID NSString *appIDFromFile = [[NSString alloc] initWithContentsOfFile:appUIDPath encoding:NSUTF8StringEncoding error:nil]; //获取keychain的UID NSString *appIDFromKeychain = [SSKeychain passwordForService:@"com.brilliantAreo.userClient"account:@"iid"]; NSString *uuidStr = nil; BOOL shouldSaveSandBox = NO; BOOL shouldSaveKeychain = NO; //同时存在 if ((appIDFromFile.length > 0) && (appIDFromKeychain.length > 0)) { uuidStr = appIDFromFile; if (![appIDFromFile isEqualToString:appIDFromKeychain]) { shouldSaveKeychain = YES; } } //沙盒不存在,Keychain存在 else if ((appIDFromFile.length == 0) && (appIDFromKeychain.length > 0)) { uuidStr = appIDFromKeychain; shouldSaveSandBox = YES; } //沙盒存在,Keychain不存在 else if ((appIDFromFile.length > 0) && (appIDFromKeychain.length == 0)) { uuidStr = appIDFromFile; shouldSaveKeychain = YES; } //同时不存在 else { if([[UIDevice currentDevice] respondsToSelector:@selector(identifierForVendor)]) { uuidStr = [[[UIDevice currentDevice] identifierForVendor] UUIDString]; shouldSaveKeychain = YES; shouldSaveSandBox = YES; } } [self setAppUID:uuidStr];//设置APPUID if (shouldSaveSandBox) { [self saveAppUID];//保存沙盒 } if (shouldSaveKeychain) { [SSKeychain setPassword:uuidStr forService:@"com.brilliantAreo.userClient" account:@"iid"];//保存Keychain } } return [identityData appUID]; } // 设置程序用户UID - (void)setAppUID:(NSString *)appUIDNew { [self initIdentityData]; [identityData setAppUID:appUIDNew]; } #pragma mark - 获取服务端分配的ServerID // =================================================================== // 获取和设置程序用户ID // =================================================================== // 获取程序ServerID - (NSString *)serverID { [self initIdentityData]; // 如果没有加载 if([identityData serverID] == nil) { // 获取document文件夹位置 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentDirectory = [paths objectAtIndex:0]; // 加载ServerID文件 NSString *serverIDPath = [documentDirectory stringByAppendingPathComponent:kServerIDFile]; // 该文件存在 if([[NSFileManager defaultManager] fileExistsAtPath:serverIDPath]) { NSString *serverIDFromFile = [[NSString alloc] initWithContentsOfFile:serverIDPath encoding:NSUTF8StringEncoding error:nil]; [self setServerID:serverIDFromFile]; } // 该文件不存在,设置成默认值(空字符串) else { [self setServerID:@""]; } } return [identityData serverID]; } // 设置程序用户ID - (void)setServerID:(NSString *)serverIDNew { [self initIdentityData]; [identityData setServerID:serverIDNew]; } #pragma mark - 获取和设置deviceUID // 获取UID - (NSString *)deviceUID { [self initIdentityData]; // 如果没有加载 if([identityData deviceUID] == nil) { // 获取document文件夹位置 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentDirectory = [paths objectAtIndex:0]; // 加载UID文件 NSString *deviceUIDPath = [documentDirectory stringByAppendingPathComponent:kDeviceUIDFile]; // 该文件存在 if([[NSFileManager defaultManager] fileExistsAtPath:deviceUIDPath]) { NSString *deviceUIDFromFile = [[NSString alloc] initWithContentsOfFile:deviceUIDPath encoding:NSUTF8StringEncoding error:nil]; [self setDeviceUID:deviceUIDFromFile]; } // 该文件不存在,则通过方式获取该唯一标识 else { // 产生唯一标识 CFUUIDRef puuid = CFUUIDCreate(nil); CFStringRef uuidString = CFUUIDCreateString(nil, puuid); NSString * deviceID = (__bridge_transfer NSString *)CFStringCreateCopy(NULL, uuidString); CFRelease(puuid); CFRelease(uuidString); [self setDeviceUID:deviceID]; // 保存到文件中 [self saveDeviceUID]; } } return [identityData deviceUID]; } // 设置UID - (void)setDeviceUID:(NSString *)deviceUIDNew { [self initIdentityData]; [identityData setDeviceUID:deviceUIDNew]; } // 获取Mac地址 // Return the local MAC addy // Courtesy of FreeBSD hackers email list // Accidentally munged during previous update. Fixed thanks to erica sadun & mlamb. + (NSString *)macAddress { int mib[6]; size_t len; char *buf; unsigned char *ptr; struct if_msghdr *ifm; struct sockaddr_dl *sdl; mib[0] = CTL_NET; mib[1] = AF_ROUTE; mib[2] = 0; mib[3] = AF_LINK; mib[4] = NET_RT_IFLIST; if ((mib[5] = if_nametoindex("en0")) == 0) { return @""; } if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { return @""; } if ((buf = malloc(len)) == NULL) { return @""; } if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) { free(buf); return @""; } ifm = (struct if_msghdr *)buf; sdl = (struct sockaddr_dl *)(ifm + 1); ptr = (unsigned char *)LLADDR(sdl); NSString *outstring = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X", *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)]; free(buf); return outstring; } // 获取platform + (NSString *)platform { size_t size; sysctlbyname("hw.machine", NULL, &size, NULL, 0); char *machine = malloc(size); sysctlbyname("hw.machine", machine, &size, NULL, 0); NSString *platform = [NSString stringWithCString:machine encoding:NSUTF8StringEncoding]; free(machine); return platform; } - (NSString *)vendorUID { // UID #if TARGET_IPHONE_SIMULATOR NSString *deviceID = @"0000000000000000000000000000000000000000"; #elif TARGET_OS_IPHONE NSString *deviceID = [DataController macAddress]; if ([deviceID isEqualToString:@"02:00:00:00:00:00"] || (deviceID == nil)) { return [self appUID]; } #endif return deviceID; } #pragma mark - 保存 // =================================================================== // 程序用户ID存储函数 // =================================================================== // 保存AppID - (void)saveAppGID { if((identityData != nil) && ([identityData appGID] != nil)) { // 获取document文件夹位置 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentDirectory = [paths objectAtIndex:0]; // 将GID数据写入文件 NSString *appGIDPath = [documentDirectory stringByAppendingPathComponent:kAppGIDFile]; [[identityData appGID] writeToFile:appGIDPath atomically:YES encoding:NSUTF8StringEncoding error:nil]; if ([[NSFileManager defaultManager] respondsToSelector:@selector(containerURLForSecurityApplicationGroupIdentifier:)]) { NSString *groupUrl = [[[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:[DataController getAppGroupID]] relativePath]; [[identityData appGID] writeToFile:[groupUrl stringByAppendingPathComponent:kAppGIDFile] atomically:YES encoding:NSUTF8StringEncoding error:nil]; } } } // 保存AppUID - (void)saveAppUID { if((identityData != nil) && ([identityData appUID] != nil)) { // 获取document文件夹位置 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentDirectory = [paths objectAtIndex:0]; // 将UID数据写入文件 NSString *appUIDPath = [documentDirectory stringByAppendingPathComponent:kAppUIDFile]; [[identityData appUID] writeToFile:appUIDPath atomically:YES encoding:NSUTF8StringEncoding error:nil]; if ([[NSFileManager defaultManager] respondsToSelector:@selector(containerURLForSecurityApplicationGroupIdentifier:)]) { NSString *groupUrl = [[[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:[DataController getAppGroupID]] relativePath]; [[identityData appUID] writeToFile:[groupUrl stringByAppendingPathComponent:kAppUIDFile] atomically:YES encoding:NSUTF8StringEncoding error:nil]; } } } // 保存ServerID - (void)saveServerID { if((identityData != nil) && ([identityData serverID] != nil)) { // 获取document文件夹位置 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentDirectory = [paths objectAtIndex:0]; // 将ServerID数据写入文件 NSString *serverIDPath = [documentDirectory stringByAppendingPathComponent:kServerIDFile]; [[identityData serverID] writeToFile:serverIDPath atomically:YES encoding:NSUTF8StringEncoding error:nil]; if ([[NSFileManager defaultManager] respondsToSelector:@selector(containerURLForSecurityApplicationGroupIdentifier:)]) { NSString *groupUrl = [[[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:[DataController getAppGroupID]] relativePath]; [[identityData serverID] writeToFile:[groupUrl stringByAppendingPathComponent:kServerIDFile] atomically:YES encoding:NSUTF8StringEncoding error:nil]; } } } // 保存UID - (void)saveDeviceUID { if((identityData != nil) && ([identityData deviceUID] != nil)) { // 获取document文件夹位置 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentDirectory = [paths objectAtIndex:0]; // 将DeviceUID数据写入文件 NSString *deviceUIDPath = [documentDirectory stringByAppendingPathComponent:kDeviceUIDFile]; [[identityData deviceUID] writeToFile:deviceUIDPath atomically:YES encoding:NSUTF8StringEncoding error:nil]; if ([[NSFileManager defaultManager] respondsToSelector:@selector(containerURLForSecurityApplicationGroupIdentifier:)]) { NSString *groupUrl = [[[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:[DataController getAppGroupID]] relativePath]; [[identityData deviceUID] writeToFile:[groupUrl stringByAppendingPathComponent:kDeviceUIDFile] atomically:YES encoding:NSUTF8StringEncoding error:nil]; } } } // 系统型号 + (NSString *)osVersion { return [[UIDevice currentDevice] systemVersion]; } // 获取App的版本号,包含buildID, 如:1.0.0-3 其中1.0.0为appVersion,3位build ID + (NSString *)appVersion { NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary]; NSString *appVersion = [infoDic objectForKey:@"CFBundleShortVersionString"]; if(appVersion.length > 0) { return [NSString stringWithFormat: @"%@-%@", appVersion, [self appBuildID]]; } return @""; } // 获取build号 + (NSString *)appBuildID { NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary]; NSString *buildId = [infoDic objectForKey:@"CFBundleVersion"]; if(buildId.length > 0) { return buildId; } return @""; } + (NSString *)deviceModelName { struct utsname systemInfo; uname(&systemInfo); NSString* code = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; static NSDictionary* deviceNamesByCode = nil; if (!deviceNamesByCode) { deviceNamesByCode = @{@"i386" : @"Simulator", @"x86_64" : @"Simulator", @"iPod1,1" : @"iPod Touch", // (Original) @"iPod2,1" : @"iPod Touch", // (Second Generation) @"iPod3,1" : @"iPod Touch", // (Third Generation) @"iPod4,1" : @"iPod Touch", // (Fourth Generation) @"iPod7,1" : @"iPod Touch", // (6th Generation) @"iPhone1,1" : @"iPhone", // (Original) @"iPhone1,2" : @"iPhone", // (3G) @"iPhone2,1" : @"iPhone", // (3GS) @"iPad1,1" : @"iPad", // (Original) @"iPad2,1" : @"iPad 2", // @"iPad3,1" : @"iPad", // (3rd Generation) @"iPhone3,1" : @"iPhone 4", // (GSM) @"iPhone3,3" : @"iPhone 4", // (CDMA/Verizon/Sprint) @"iPhone4,1" : @"iPhone 4S", // @"iPhone5,1" : @"iPhone 5", // (model A1428, AT&T/Canada) @"iPhone5,2" : @"iPhone 5", // (model A1429, everything else) @"iPad3,4" : @"iPad", // (4th Generation) @"iPad2,5" : @"iPad Mini", // (Original) @"iPhone5,3" : @"iPhone 5c", // (model A1456, A1532 | GSM) @"iPhone5,4" : @"iPhone 5c", // (model A1507, A1516, A1526 (China), A1529 | Global) @"iPhone6,1" : @"iPhone 5s", // (model A1433, A1533 | GSM) @"iPhone6,2" : @"iPhone 5s", // (model A1457, A1518, A1528 (China), A1530 | Global) @"iPhone7,1" : @"iPhone 6 Plus", // @"iPhone7,2" : @"iPhone 6", // @"iPhone8,1" : @"iPhone 6S", // @"iPhone8,2" : @"iPhone 6S Plus", // @"iPhone8,4" : @"iPhone SE", // @"iPhone9,1" : @"iPhone 7", // @"iPhone9,3" : @"iPhone 7", // @"iPhone9,2" : @"iPhone 7 Plus", // @"iPhone9,4" : @"iPhone 7 Plus", // @"iPhone10,1": @"iPhone 8", // CDMA @"iPhone10,4": @"iPhone 8", // GSM @"iPhone10,2": @"iPhone 8 Plus", // CDMA @"iPhone10,5": @"iPhone 8 Plus", // GSM @"iPhone10,3": @"iPhone X", // CDMA @"iPhone10,6": @"iPhone X", // GSM @"iPad4,1" : @"iPad Air", // 5th Generation iPad (iPad Air) - Wifi @"iPad4,2" : @"iPad Air", // 5th Generation iPad (iPad Air) - Cellular @"iPad4,4" : @"iPad Mini", // (2nd Generation iPad Mini - Wifi) @"iPad4,5" : @"iPad Mini", // (2nd Generation iPad Mini - Cellular) @"iPad4,7" : @"iPad Mini", // (3rd Generation iPad Mini - Wifi (model A1599)) @"iPad6,7" : @"iPad Pro (12.9\")", // iPad Pro 12.9 inches - (model A1584) @"iPad6,8" : @"iPad Pro (12.9\")", // iPad Pro 12.9 inches - (model A1652) @"iPad6,3" : @"iPad Pro (9.7\")", // iPad Pro 9.7 inches - (model A1673) @"iPad6,4" : @"iPad Pro (9.7\")" // iPad Pro 9.7 inches - (models A1674 and A1675) }; } NSString* deviceName = [deviceNamesByCode objectForKey:code]; if (!deviceName) { // Not found on database. At least guess main device type from string contents: if ([code rangeOfString:@"iPod"].location != NSNotFound) { deviceName = @"iPod Touch"; } else if([code rangeOfString:@"iPad"].location != NSNotFound) { deviceName = @"iPad"; } else if([code rangeOfString:@"iPhone"].location != NSNotFound){ deviceName = @"iPhone"; } else { deviceName = @"Unknown"; } } return deviceName; } + (NSString *)bundleID { return [[NSBundle mainBundle] bundleIdentifier]; } // 用户所在的运营商 + (id)getCarrierCode { // 判断是否能够取得运营商 Class telephoneNetWorkClass = (NSClassFromString(@"CTTelephonyNetworkInfo")); if (telephoneNetWorkClass != nil) { CTTelephonyNetworkInfo *telephonyNetworkInfo = [[CTTelephonyNetworkInfo alloc] init]; // 获得运营商的信息 Class carrierClass = (NSClassFromString(@"CTCarrier")); if (carrierClass != nil) { CTCarrier *carrier = telephonyNetworkInfo.subscriberCellularProvider; // 移动运营商的mcc 和 mnc NSString * mobileCountryCode = [carrier mobileCountryCode]; NSString * mobileNetworkCode = [carrier mobileNetworkCode]; // 统计能够取到信息的运营商 if ((mobileCountryCode != nil) && (mobileNetworkCode != nil)) { NSString *mobileCode = [[NSString alloc] initWithFormat:@"%@%@", mobileCountryCode, mobileNetworkCode]; return mobileCode; } } } return [NSNull null]; } @end