2016.07.01git
更新至iPhone X 新增設備顏色的獲取github
爲了統計用戶信息、下發廣告,服務器端每每須要手機用戶設備及app的各類信息,下面講述一下各類信息的獲取方式:數據庫
// 這個方法後面會列出來
NSString *deviceName = [self getDeviceName];
NSLog(@"設備型號-->%@", deviceName);
NSString *iPhoneName = [UIDevice currentDevice].name;
NSLog(@"iPhone名稱-->%@", iPhoneName);
NSString *appVerion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
NSLog(@"app版本號-->%@", appVerion);
CGFloat batteryLevel = [[UIDevice currentDevice] batteryLevel];
NSLog(@"電池電量-->%f", batteryLevel);
NSString *localizedModel = [UIDevice currentDevice].localizedModel;
NSLog(@"localizedModel-->%@", localizedModel);
NSString *systemName = [UIDevice currentDevice].systemName;
NSLog(@"當前系統名稱-->%@", systemName);
NSString *systemVersion = [UIDevice currentDevice].systemVersion;
NSLog(@"當前系統版本號-->%@", systemVersion);
struct utsname systemInfo;
uname(&systemInfo);
NSString *device_model = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
NSLog(@"device_model-->%@", device_model);
// 這個方法後面會單獨列出
NSString *macAddress = [self getMacAddress];
NSLog(@"macAddress-->%@", macAddress);
// 這個方法後面會單獨列出
NSString *deviceIP = [self getDeviceIPAddresses];
NSLog(@"deviceIP-->%@", deviceIP);
// 設備上次重啓的時間
NSTimeInterval time = [[NSProcessInfo processInfo] systemUptime];
NSDate *lastRestartDate = [[NSDate alloc] initWithTimeIntervalSinceNow:(0 - time)];
複製代碼
NSString *idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
NSLog(@"廣告位標識符idfa-->%@", idfa);
複製代碼
NSString *uuid = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
NSLog(@"惟一識別碼uuid-->%@", uuid);
複製代碼
// 獲取設備型號而後手動轉化爲對應名稱
- (NSString *)getDeviceName
{
// 須要#import "sys/utsname.h"
#warning 題主嘔心瀝血總結!!最全面!親測!全網獨此一份!!
struct utsname systemInfo;
uname(&systemInfo);
NSString *deviceString = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
if ([deviceString isEqualToString:@"iPhone3,1"]) return @"iPhone 4";
if ([deviceString isEqualToString:@"iPhone3,2"]) return @"iPhone 4";
if ([deviceString isEqualToString:@"iPhone3,3"]) return @"iPhone 4";
if ([deviceString isEqualToString:@"iPhone4,1"]) return @"iPhone 4S";
if ([deviceString isEqualToString:@"iPhone5,1"]) return @"iPhone 5";
if ([deviceString isEqualToString:@"iPhone5,2"]) return @"iPhone 5 (GSM+CDMA)";
if ([deviceString isEqualToString:@"iPhone5,3"]) return @"iPhone 5c (GSM)";
if ([deviceString isEqualToString:@"iPhone5,4"]) return @"iPhone 5c (GSM+CDMA)";
if ([deviceString isEqualToString:@"iPhone6,1"]) return @"iPhone 5s (GSM)";
if ([deviceString isEqualToString:@"iPhone6,2"]) return @"iPhone 5s (GSM+CDMA)";
if ([deviceString isEqualToString:@"iPhone7,1"]) return @"iPhone 6 Plus";
if ([deviceString isEqualToString:@"iPhone7,2"]) return @"iPhone 6";
if ([deviceString isEqualToString:@"iPhone8,1"]) return @"iPhone 6s";
if ([deviceString isEqualToString:@"iPhone8,2"]) return @"iPhone 6s Plus";
if ([deviceString isEqualToString:@"iPhone8,4"]) return @"iPhone SE";
// 日行兩款手機型號均爲日本獨佔,可能使用索尼FeliCa支付方案而不是蘋果支付
if ([deviceString isEqualToString:@"iPhone9,1"]) return @"國行、日版、港行iPhone 7";
if ([deviceString isEqualToString:@"iPhone9,2"]) return @"港行、國行iPhone 7 Plus";
if ([deviceString isEqualToString:@"iPhone9,3"]) return @"美版、臺版iPhone 7";
if ([deviceString isEqualToString:@"iPhone9,4"]) return @"美版、臺版iPhone 7 Plus";
if ([deviceString isEqualToString:@"iPhone10,1"]) return @"國行(A1863)、日行(A1906)iPhone 8";
if ([deviceString isEqualToString:@"iPhone10,4"]) return @"美版(Global/A1905)iPhone 8";
if ([deviceString isEqualToString:@"iPhone10,2"]) return @"國行(A1864)、日行(A1898)iPhone 8 Plus";
if ([deviceString isEqualToString:@"iPhone10,5"]) return @"美版(Global/A1897)iPhone 8 Plus";
if ([deviceString isEqualToString:@"iPhone10,3"]) return @"國行(A1865)、日行(A1902)iPhone X";
if ([deviceString isEqualToString:@"iPhone10,6"]) return @"美版(Global/A1901)iPhone X";
if ([deviceString isEqualToString:@"iPod1,1"]) return @"iPod Touch 1G";
if ([deviceString isEqualToString:@"iPod2,1"]) return @"iPod Touch 2G";
if ([deviceString isEqualToString:@"iPod3,1"]) return @"iPod Touch 3G";
if ([deviceString isEqualToString:@"iPod4,1"]) return @"iPod Touch 4G";
if ([deviceString isEqualToString:@"iPod5,1"]) return @"iPod Touch (5 Gen)";
if ([deviceString isEqualToString:@"iPad1,1"]) return @"iPad";
if ([deviceString isEqualToString:@"iPad1,2"]) return @"iPad 3G";
if ([deviceString isEqualToString:@"iPad2,1"]) return @"iPad 2 (WiFi)";
if ([deviceString isEqualToString:@"iPad2,2"]) return @"iPad 2";
if ([deviceString isEqualToString:@"iPad2,3"]) return @"iPad 2 (CDMA)";
if ([deviceString isEqualToString:@"iPad2,4"]) return @"iPad 2";
if ([deviceString isEqualToString:@"iPad2,5"]) return @"iPad Mini (WiFi)";
if ([deviceString isEqualToString:@"iPad2,6"]) return @"iPad Mini";
if ([deviceString isEqualToString:@"iPad2,7"]) return @"iPad Mini (GSM+CDMA)";
if ([deviceString isEqualToString:@"iPad3,1"]) return @"iPad 3 (WiFi)";
if ([deviceString isEqualToString:@"iPad3,2"]) return @"iPad 3 (GSM+CDMA)";
if ([deviceString isEqualToString:@"iPad3,3"]) return @"iPad 3";
if ([deviceString isEqualToString:@"iPad3,4"]) return @"iPad 4 (WiFi)";
if ([deviceString isEqualToString:@"iPad3,5"]) return @"iPad 4";
if ([deviceString isEqualToString:@"iPad3,6"]) return @"iPad 4 (GSM+CDMA)";
if ([deviceString isEqualToString:@"iPad4,1"]) return @"iPad Air (WiFi)";
if ([deviceString isEqualToString:@"iPad4,2"]) return @"iPad Air (Cellular)";
if ([deviceString isEqualToString:@"iPad4,4"]) return @"iPad Mini 2 (WiFi)";
if ([deviceString isEqualToString:@"iPad4,5"]) return @"iPad Mini 2 (Cellular)";
if ([deviceString isEqualToString:@"iPad4,6"]) return @"iPad Mini 2";
if ([deviceString isEqualToString:@"iPad4,7"]) return @"iPad Mini 3";
if ([deviceString isEqualToString:@"iPad4,8"]) return @"iPad Mini 3";
if ([deviceString isEqualToString:@"iPad4,9"]) return @"iPad Mini 3";
if ([deviceString isEqualToString:@"iPad5,1"]) return @"iPad Mini 4 (WiFi)";
if ([deviceString isEqualToString:@"iPad5,2"]) return @"iPad Mini 4 (LTE)";
if ([deviceString isEqualToString:@"iPad5,3"]) return @"iPad Air 2";
if ([deviceString isEqualToString:@"iPad5,4"]) return @"iPad Air 2";
if ([deviceString isEqualToString:@"iPad6,3"]) return @"iPad Pro 9.7";
if ([deviceString isEqualToString:@"iPad6,4"]) return @"iPad Pro 9.7";
if ([deviceString isEqualToString:@"iPad6,7"]) return @"iPad Pro 12.9";
if ([deviceString isEqualToString:@"iPad6,8"]) return @"iPad Pro 12.9";
if ([machineString isEqualToString:@"iPad6,11"]) return @"iPad 5 (WiFi)";
if ([machineString isEqualToString:@"iPad6,12"]) return @"iPad 5 (Cellular)";
if ([machineString isEqualToString:@"iPad7,1"]) return @"iPad Pro 12.9 inch 2nd gen (WiFi)";
if ([machineString isEqualToString:@"iPad7,2"]) return @"iPad Pro 12.9 inch 2nd gen (Cellular)";
if ([machineString isEqualToString:@"iPad7,3"]) return @"iPad Pro 10.5 inch (WiFi)";
if ([machineString isEqualToString:@"iPad7,4"]) return @"iPad Pro 10.5 inch (Cellular)";
if ([deviceString isEqualToString:@"AppleTV2,1"]) return @"Apple TV 2";
if ([deviceString isEqualToString:@"AppleTV3,1"]) return @"Apple TV 3";
if ([deviceString isEqualToString:@"AppleTV3,2"]) return @"Apple TV 3";
if ([deviceString isEqualToString:@"AppleTV5,3"]) return @"Apple TV 4";
if ([deviceString isEqualToString:@"i386"]) return @"Simulator";
if ([deviceString isEqualToString:@"x86_64"]) return @"Simulator";
return deviceString;
}
複製代碼
#warning 該方法是私有API,上線會被拒
// 因爲每款手機同一顏色具體色號不同,如 iPhone 6和 iPhone SE粉色的兩個具體色值是不同的,所以在這裏只能返回一個色號
UIDevice *device = [UIDevice currentDevice];
SEL selector = NSSelectorFromString(@"deviceInfoForKey:");
if (![device respondsToSelector:selector]) {
selector = NSSelectorFromString(@"_deviceInfoForKey:");
}
if ([device respondsToSelector:selector]) {
// 消除警告「performSelector may cause a leak because its selector is unknown」
IMP imp = [device methodForSelector:selector];
NSString * (*func)(id, SEL, NSString *) = (void *)imp;
NSString *deviceColor = func(device, selector, @"DeviceColor");
NSString *deviceEnclosureColor = func(device, selector, @"DeviceEnclosureColor");
NSLog(@"deviceColor --> %@ \n @"deviceEnclosureColor --> %@ ", deviceColor, deviceEnclosureColor);
}
複製代碼
這裏是一些已知的設備顏色數據結構
- (NSString *)getMacAddress {
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) {
printf("Error: if_nametoindex error/n");
return NULL;
}
if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
printf("Error: sysctl, take 1/n");
return NULL;
}
if ((buf = malloc(len)) == NULL) {
printf("Could not allocate memory. error!/n");
return NULL;
}
if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
printf("Error: sysctl, take 2");
return NULL;
}
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 uppercaseString];
}
複製代碼
- (NSString *)getDeviceIPAddresses {
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
NSMutableArray *ips = [NSMutableArray array];
int BUFFERSIZE = 4096;
struct ifconf ifc;
char buffer[BUFFERSIZE], *ptr, lastname[IFNAMSIZ], *cptr;
struct ifreq *ifr, ifrcopy;
ifc.ifc_len = BUFFERSIZE;
ifc.ifc_buf = buffer;
if (ioctl(sockfd, SIOCGIFCONF, &ifc) >= 0){
for (ptr = buffer; ptr < buffer + ifc.ifc_len; ){
ifr = (struct ifreq *)ptr;
int len = sizeof(struct sockaddr);
if (ifr->ifr_addr.sa_len > len) {
len = ifr->ifr_addr.sa_len;
}
ptr += sizeof(ifr->ifr_name) + len;
if (ifr->ifr_addr.sa_family != AF_INET) continue;
if ((cptr = (char *)strchr(ifr->ifr_name, ':')) != NULL) *cptr = 0;
if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) continue;
memcpy(lastname, ifr->ifr_name, IFNAMSIZ);
ifrcopy = *ifr;
ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy);
if ((ifrcopy.ifr_flags & IFF_UP) == 0) continue;
NSString *ip = [NSString stringWithFormat:@"%s", inet_ntoa(((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr)];
[ips addObject:ip];
}
}
close(sockfd);
NSString *deviceIP = @"";
for (int i=0; i < ips.count; i++) {
if (ips.count > 0) {
deviceIP = [NSString stringWithFormat:@"%@",ips.lastObject];
}
}
return deviceIP;
}
複製代碼
// CPU總數目
- (NSUInteger)getCPUCount {
return [NSProcessInfo processInfo].activeProcessorCount;
}
// 已使用的CPU比例
- (float)getCPUUsage {
float cpu = 0;
NSArray *cpus = [self getPerCPUUsage];
if (cpus.count == 0) return -1;
for (NSNumber *n in cpus) {
cpu += n.floatValue;
}
return cpu;
}
// 獲取每一個cpu的使用比例
- (NSArray *)getPerCPUUsage {
processor_info_array_t _cpuInfo, _prevCPUInfo = nil;
mach_msg_type_number_t _numCPUInfo, _numPrevCPUInfo = 0;
unsigned _numCPUs;
NSLock *_cpuUsageLock;
int _mib[2U] = { CTL_HW, HW_NCPU };
size_t _sizeOfNumCPUs = sizeof(_numCPUs);
int _status = sysctl(_mib, 2U, &_numCPUs, &_sizeOfNumCPUs, NULL, 0U);
if (_status)
_numCPUs = 1;
_cpuUsageLock = [[NSLock alloc] init];
natural_t _numCPUsU = 0U;
kern_return_t err = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &_numCPUsU, &_cpuInfo, &_numCPUInfo);
if (err == KERN_SUCCESS) {
[_cpuUsageLock lock];
NSMutableArray *cpus = [NSMutableArray new];
for (unsigned i = 0U; i < _numCPUs; ++i) {
Float32 _inUse, _total;
if (_prevCPUInfo) {
_inUse = (
(_cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_USER] - _prevCPUInfo[(CPU_STATE_MAX * i) + CPU_STATE_USER])
+ (_cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_SYSTEM] - _prevCPUInfo[(CPU_STATE_MAX * i) + CPU_STATE_SYSTEM])
+ (_cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_NICE] - _prevCPUInfo[(CPU_STATE_MAX * i) + CPU_STATE_NICE])
);
_total = _inUse + (_cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_IDLE] - _prevCPUInfo[(CPU_STATE_MAX * i) + CPU_STATE_IDLE]);
} else {
_inUse = _cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_USER] + _cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_SYSTEM] + _cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_NICE];
_total = _inUse + _cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_IDLE];
}
[cpus addObject:@(_inUse / _total)];
}
[_cpuUsageLock unlock];
if (_prevCPUInfo) {
size_t prevCpuInfoSize = sizeof(integer_t) * _numPrevCPUInfo;
vm_deallocate(mach_task_self(), (vm_address_t)_prevCPUInfo, prevCpuInfoSize);
}
return cpus;
} else {
return nil;
}
}
複製代碼
// 獲取磁盤總空間
- (int64_t)getTotalDiskSpace {
NSError *error = nil;
NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:&error];
if (error) return -1;
int64_t space = [[attrs objectForKey:NSFileSystemSize] longLongValue];
if (space < 0) space = -1;
return space;
}
// 獲取未使用的磁盤空間
- (int64_t)getFreeDiskSpace {
NSError *error = nil;
NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:&error];
if (error) return -1;
int64_t space = [[attrs objectForKey:NSFileSystemFreeSize] longLongValue];
if (space < 0) space = -1;
return space;
}
// 獲取已使用的磁盤空間
- (int64_t)getUsedDiskSpace {
int64_t totalDisk = [self getTotalDiskSpace];
int64_t freeDisk = [self getFreeDiskSpace];
if (totalDisk < 0 || freeDisk < 0) return -1;
int64_t usedDisk = totalDisk - freeDisk;
if (usedDisk < 0) usedDisk = -1;
return usedDisk;
}
複製代碼
// 系統總內存空間
- (int64_t)getTotalMemory {
int64_t totalMemory = [[NSProcessInfo processInfo] physicalMemory];
if (totalMemory < -1) totalMemory = -1;
return totalMemory;
}
// 活躍的內存,正在使用或者很短期內被使用過
- (int64_t)getActiveMemory {
mach_port_t host_port = mach_host_self();
mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
vm_size_t page_size;
vm_statistics_data_t vm_stat;
kern_return_t kern;
kern = host_page_size(host_port, &page_size);
if (kern != KERN_SUCCESS) return -1;
kern = host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size);
if (kern != KERN_SUCCESS) return -1;
return vm_stat.active_count * page_size;
}
// 最近使用過,可是目前處於不活躍狀態的內存
- (int64_t)getInActiveMemory {
mach_port_t host_port = mach_host_self();
mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
vm_size_t page_size;
vm_statistics_data_t vm_stat;
kern_return_t kern;
kern = host_page_size(host_port, &page_size);
if (kern != KERN_SUCCESS) return -1;
kern = host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size);
if (kern != KERN_SUCCESS) return -1;
return vm_stat.inactive_count * page_size;
}
// 空閒的內存空間
- (int64_t)getFreeMemory {
mach_port_t host_port = mach_host_self();
mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
vm_size_t page_size;
vm_statistics_data_t vm_stat;
kern_return_t kern;
kern = host_page_size(host_port, &page_size);
if (kern != KERN_SUCCESS) return -1;
kern = host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size);
if (kern != KERN_SUCCESS) return -1;
return vm_stat.free_count * page_size;
}
// 已使用的內存空間
- (int64_t)getUsedMemory {
mach_port_t host_port = mach_host_self();
mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
vm_size_t page_size;
vm_statistics_data_t vm_stat;
kern_return_t kern;
kern = host_page_size(host_port, &page_size);
if (kern != KERN_SUCCESS) return -1;
kern = host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size);
if (kern != KERN_SUCCESS) return -1;
return page_size * (vm_stat.active_count + vm_stat.inactive_count + vm_stat.wire_count);
}
// 用來存放內核和數據結構的內存,framework、用戶級別的應用沒法分配
- (int64_t)getWiredMemory {
mach_port_t host_port = mach_host_self();
mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
vm_size_t page_size;
vm_statistics_data_t vm_stat;
kern_return_t kern;
kern = host_page_size(host_port, &page_size);
if (kern != KERN_SUCCESS) return -1;
kern = host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size);
if (kern != KERN_SUCCESS) return -1;
return vm_stat.wire_count * page_size;
}
// 可釋放的內存空間:內存吃緊自動釋放,針對大對象存放所需的大塊內存空間
- (int64_t)getPurgableMemory {
mach_port_t host_port = mach_host_self();
mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
vm_size_t page_size;
vm_statistics_data_t vm_stat;
kern_return_t kern;
kern = host_page_size(host_port, &page_size);
if (kern != KERN_SUCCESS) return -1;
kern = host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size);
if (kern != KERN_SUCCESS) return -1;
return vm_stat.purgeable_count * page_size;
}
複製代碼
再放一下GitHub源碼app