在項(xiàng)目中經(jīng)常會(huì)遇到要向服務(wù)端提交設(shè)備相關(guān)信息的需求(設(shè)備型號(hào)、版本號(hào)、DeviceToken等等),于是把當(dāng)前用到的相關(guān)函數(shù)整理成一個(gè)工具類和大家分享~~
YBDeviceManager.h
// YBDeviceManager.h
// SHARE
//
// Created by IDBENY on 2017/6/6.
// Copyright ? 2017年 Personal:idbeny.com All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
//mac
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
#import <sys/sockio.h>
#import <sys/ioctl.h>
#import <arpa/inet.h>
//IP
#include <ifaddrs.h>
#include <sys/stat.h>
#include <sys/mount.h>
#import <sys/utsname.h>
#import <Security/Security.h>
//CPU
#include <mach/mach.h>
//廣告
#import <AdSupport/AdSupport.h>
typedef enum : NSUInteger {
MemoryTypeTotal = 0,//總的
MemoryTypeFree, //剩余
MemoryTypeUsed, //已用
MemoryTypeActive, //活躍
MemoryTypeInactive, //不活躍
MemoryTypeWired, //存放內(nèi)核和數(shù)據(jù)結(jié)構(gòu)
MemoryTypePurgeable //可釋放的
} MemoryType;
static inline BOOL iOS7AndLater(){
return [[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0;
}
static inline BOOL iOS8AndLater(){
return [[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0;
}
static inline BOOL iOS9AndLater(){
return [[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0;
}
static inline BOOL iOS10AndLater(){
return [[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0;
}
static inline BOOL iOS11AndLater(){
return [[[UIDevice currentDevice] systemVersion] floatValue] >= 11.0;
}
@interface YBDeviceManager : NSObject
+ (instancetype)defaultManager;
/**
獲取UUID
@return UUID
*/
- (NSString *)getDeviceUUID;
/**
創(chuàng)建UUID
@return UUID
*/
- (NSString *)createNewUUID;
/**
獲取DeviceToken
@return DeviceToken
*/
- (NSString *)getDeviceToken;
/**
獲取當(dāng)前設(shè)備Model
@return iPhone/iPad/iPod touch/...
*/
- (NSString *)deviceModel;
/**
獲取當(dāng)前設(shè)備名稱
@return iPhone 6 Plus/iPhone SE/iPad Mini/...
*/
- (NSString *)getDeviceName;
/**
獲取廣告標(biāo)識(shí)符
@return IDFA
*/
- (NSString *)getIDFA;
/**
獲取設(shè)備IP地址
@return deviceIP
*/
- (NSString *)getDeviceIPAddress;
/**
獲取WiFi地址
@return WiFiIP
*/
- (NSString *)getIPAddressForWiFi;
/**
獲取移動(dòng)網(wǎng)絡(luò)IP
@return mobileNetworkIP
*/
- (NSString *)getIPAddressForMobileNetwork;
/**
獲取MAC地址
@return MAC
*/
- (NSString *)getMACAddress;
/**
系統(tǒng)版本
@return e.g 7.0/8.3/..
*/
- (NSString *)systemVersion;
/**
當(dāng)前APP版本
@return e.g 3.0.0/3.0.1/...
*/
- (NSString *)appVersion;
/**
獲取區(qū)域標(biāo)志符(非語言標(biāo)志)
@return e.g en_GB...
*/
- (NSString *)localeIdentifier;
/**
判斷設(shè)備是否為iPad
@return NO:iPhone/TV/CarPlay YES:iPad
*/
- (BOOL)isiPad;
/**
是否為視網(wǎng)膜屏幕
@return YES/NO
*/
- (BOOL)isRetina;
/**
判斷系統(tǒng)版本
@return YES/NO
*/
- (BOOL)iOS7AndLater;
- (BOOL)iOS8AndLater;
- (BOOL)iOS9AndLater;
- (BOOL)iOS10AndLater;
- (BOOL)iOS11AndLater;
/**
判斷相機(jī)是否可用(前置)
@return YES/NO
*/
- (BOOL)isFrontCameraAvailable;
/**
判斷相機(jī)是否可用(后置)
@return YES/NO
*/
- (BOOL)isRearCameraAvailable;
/**
電量
@return battery
*/
- (float)batteryLevel;
/**
系統(tǒng)上次啟動(dòng)時(shí)間
@return NSDate*
*/
- (NSDate *)getSystemUptime;
/**
獲取CPU總數(shù)
@return CPU數(shù)量
*/
- (NSUInteger)getCPUCount;
/**
CPU使用總比例
@return CPU usage
*/
- (float)getCPUUsage;
/**
每個(gè)CPU使用比例
@return CPU usage
*/
- (NSArray *)getPerCPUUsage;
/**
獲取總磁盤空間
@return total disk space
*/
- (int64_t)getTotalDiskSpace;
- (uint64_t)c_totalDiskSpace;
/**
獲取剩余磁盤空間
@return free disk space
*/
- (int64_t)getFreeDiskSpace;
- (uint64_t)c_freeDiskSpace;
/**
獲取已使用磁盤空間
@return used disk space
*/
- (int64_t)getUsedDiskSpace;
/**
獲取磁盤設(shè)備號(hào)
@return NSNumber*
*/
- (NSNumber *)diskNumber;
/**
獲取指定目錄大小
@param dir 文件地址
@return 文件夾大小
*/
- (int64_t)sizeOfDirectory:(NSString *)dir;
/**
大小轉(zhuǎn)換
@param size bit
@return 轉(zhuǎn)換結(jié)果
*/
- (NSString *)convertFloatSizeToString:(float)size;
/**
獲取系統(tǒng)總內(nèi)存空間
@return total memory
*/
- (int64_t)getTotalMemory;
- (float)c_totalMemory;
/**
獲取系統(tǒng)活躍內(nèi)存空間
@return active memory
*/
- (int64_t)getActiveMemory;
- (float)c_activeMemory;
/**
獲取系統(tǒng)不活躍內(nèi)存空間
@return inactive memory
*/
- (int64_t)getInactiveMemory;
- (float)c_inactiveMemory;
/**
獲取系統(tǒng)空閑的內(nèi)存空間
@return free memory
*/
- (int64_t)getFreeMemory;
- (float)c_freeMemory;
/**
用戶可使用內(nèi)存
@return free memory
*/
- (float)c_userMemory;
/**
獲取系統(tǒng)已使用的內(nèi)存空間
@return used memory
*/
- (int64_t)getUsedMemory;
- (float)c_usedMemory;
/**
獲取用來存放內(nèi)核和數(shù)據(jù)結(jié)構(gòu)的內(nèi)存
@return wired memory
*/
- (int64_t)getWiredMemory;
- (float)c_wireMemory;
/**
可釋放的內(nèi)存空間:內(nèi)存吃緊自動(dòng)釋放
@return purgeable memory
*/
- (int64_t)getPurgeableMemory;
- (float)c_purgeableMemory;
/**
CPU使用頻率
@return frequency
*/
- (float)cpuFrequency;
/**
CPU總線頻率
@return frequency
*/
- (float)busFrequency;
/**
最大Socket緩存區(qū)大小
@return size
*/
- (float)maxSocketBufferSize;
@end
YBDeviceManager.m
//
// YBDeviceManager.m
// SHARE
//
// Created by IDBENY on 2017/6/6.
// Copyright ? 2017年 Personal:idbeny.com All rights reserved.
//
#import "YBDeviceManager.h"
@implementation YBDeviceManager
+ (instancetype)defaultManager {
static YBDeviceManager *defaultManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
defaultManager = [[YBDeviceManager alloc] init];
});
return defaultManager;
}
#pragma mark - ============== 獲取設(shè)備UUID ==============
- (NSString *)getDeviceUUID {
CFUUIDRef new_uuid = CFUUIDCreate(nil);
CFStringRef uuidString = CFUUIDCreateString(nil, new_uuid);
NSString * result = (NSString *)CFBridgingRelease(CFStringCreateCopy( NULL, uuidString));
CFRelease(new_uuid);
CFRelease(uuidString);
NSString *UUID = [[result description] stringByReplacingOccurrencesOfString:@"-" withString:@""];
return UUID;
}
#pragma mark - ============== 創(chuàng)建新的UUID ==============
- (NSString *)createNewUUID {
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
return (__bridge NSString *)string;
}
#pragma mark - ============== 獲取DeviceToken ==============
- (NSString *)getDeviceToken {
NSString *token = [[NSUserDefaults standardUserDefaults] objectForKey:@"deviceToken"];
return token.length > 0 ? token : nil;
}
//獲取當(dāng)前設(shè)備的model
- (NSString *)deviceModel {
struct utsname systemInfo;
uname(&systemInfo);
NSString *deviceModel = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
return deviceModel;
}
#pragma mark - ============== 獲取當(dāng)前設(shè)備的名稱 ==============
- (NSString *)getDeviceName {
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";
if ([deviceString isEqualToString:@"iPhone9,1"]) return @"國(guó)行、日版、港行iPhone 7";
if ([deviceString isEqualToString:@"iPhone9,2"]) return @"港行、國(guó)行iPhone 7 Plus";
if ([deviceString isEqualToString:@"iPhone9,3"]) return @"美版、臺(tái)版iPhone 7";
if ([deviceString isEqualToString:@"iPhone9,4"]) return @"美版、臺(tái)版iPhone 7 Plus";
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 ([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 @"i386Simulator";
if ([deviceString isEqualToString:@"x86_64"]) return @"x86_64Simulator";
return deviceString;
}
#pragma mark - ============== 獲取廣告標(biāo)識(shí)符 ==============
- (NSString *)getIDFA {
return [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
}
#pragma mark - ============== 獲取設(shè)備IP地址 ==============
- (NSString *)getDeviceIPAddress {
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;
}
#pragma mark - ============== 獲取wifi地址 ==============
- (NSString *)getIPAddressForWiFi {
return [self ipAddressWithIfaName:@"en0"];
}
#pragma mark - ============== 獲取移動(dòng)網(wǎng)絡(luò)地址 ==============
- (NSString *)getIPAddressForMobileNetwork{
return [self ipAddressWithIfaName:@"pdp_ip0"];
}
- (NSString *)ipAddressWithIfaName:(NSString *)name {
if (name.length == 0) return nil;
NSString *address = nil;
struct ifaddrs *addrs = NULL;
if (getifaddrs(&addrs) == 0) {
struct ifaddrs *addr = addrs;
while (addr) {
if ([[NSString stringWithUTF8String:addr->ifa_name] isEqualToString:name]) {
sa_family_t family = addr->ifa_addr->sa_family;
switch (family) {
case AF_INET: { // IPv4
char str[INET_ADDRSTRLEN] = {0};
inet_ntop(family, &(((struct sockaddr_in *)addr->ifa_addr)->sin_addr), str, sizeof(str));
if (strlen(str) > 0) {
address = [NSString stringWithUTF8String:str];
}
} break;
case AF_INET6: { // IPv6
char str[INET6_ADDRSTRLEN] = {0};
inet_ntop(family, &(((struct sockaddr_in6 *)addr->ifa_addr)->sin6_addr), str, sizeof(str));
if (strlen(str) > 0) {
address = [NSString stringWithUTF8String:str];
}
}
default: break;
}
if (address) break;
}
addr = addr->ifa_next;
}
}
freeifaddrs(addrs);
return address ? address : @"該設(shè)備不存在該ip地址";
}
#pragma mark - ============== 獲取MAC地址(為了保護(hù)用戶隱私,每次都不一樣) ==============
- (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];
}
#pragma mark - ============== 系統(tǒng)版本 ==============
- (NSString *)systemVersion {
UIDevice *device=[UIDevice currentDevice];
return device.systemVersion;
}
#pragma mark - ============== APP version ==============
- (NSString *)appVersion {
NSString *majorVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
return majorVersion;
}
//電池量
- (float)batteryLevel{
return [[UIDevice currentDevice] batteryLevel];
}
//獲取區(qū)域標(biāo)志符(非語言標(biāo)志)
- (NSString *)localeIdentifier {
NSLocale *frLocale = [NSLocale autoupdatingCurrentLocale];
return frLocale.localeIdentifier;
}
#pragma mark - ============== 系統(tǒng)上次啟動(dòng)時(shí)間 ==============
- (NSDate *)getSystemUptime {
NSTimeInterval time = [[NSProcessInfo processInfo] systemUptime];
return [[NSDate alloc] initWithTimeIntervalSinceNow:(0 - time)];
}
#pragma mark - ============== 判斷設(shè)備是否為iPad ==============
- (BOOL)isiPad{
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
}
#pragma mark - ============== 判斷是否為視網(wǎng)膜屏幕 ==============
- (BOOL)isRetina{
return ([UIScreen mainScreen].scale > 1.0);
}
#pragma mark - ============== 判斷系統(tǒng)版本 ==============
- (BOOL)iOS7AndLater{
return [[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0;
}
- (BOOL)iOS8AndLater{
return [[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0;
}
- (BOOL)iOS9AndLater{
return [[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0;
}
- (BOOL)iOS10AndLater{
return [[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0;
}
- (BOOL)iOS11AndLater{
return [[[UIDevice currentDevice] systemVersion] floatValue] >= 11.0;
}
#pragma mark - ============== 判斷相機(jī)是否可用 ==============
//判斷相機(jī)是否可用(前置)
- (BOOL)isFrontCameraAvailable{
return [UIImagePickerController isCameraDeviceAvailable: UIImagePickerControllerCameraDeviceFront];
}
//判斷相機(jī)是否可用(后置)
- (BOOL)isRearCameraAvailable{
return [UIImagePickerController isCameraDeviceAvailable: UIImagePickerControllerCameraDeviceRear];
}
#pragma mark - ============== CPU ==============
//CPU總數(shù)
- (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;
}
//每個(gè)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;
}
}
#pragma mark - ============== Disk ==============
//總磁盤空間
- (int64_t)getTotalDiskSpace {
return [self ios_getSpaceForKey:NSFileSystemSize];
}
- (uint64_t)c_totalDiskSpace {
NSString *str = @"~/Documents";
uint64_t size = 0;
struct statfs diskInfo;
if(statfs([[str stringByExpandingTildeInPath] fileSystemRepresentation], &diskInfo) == 0) {
//每個(gè)block里包含的字節(jié)數(shù)
uint64_t blocksize = diskInfo.f_bsize;
//總的字節(jié)數(shù),f_blocks為block的數(shù)目
uint64_t totalsize = blocksize * diskInfo.f_blocks;
size = totalsize;
}
return size;
}
//剩余磁盤空間
- (int64_t)getFreeDiskSpace {
return [self ios_getSpaceForKey:NSFileSystemFreeSize];
}
- (uint64_t)c_freeDiskSpace {
NSString *str = @"~/Documents";
uint64_t size = 0;
struct statfs diskInfo;
if(statfs([[str stringByExpandingTildeInPath] fileSystemRepresentation], &diskInfo) == 0) {
//每個(gè)block里包含的字節(jié)數(shù)
uint64_t blocksize = diskInfo.f_bsize;
//可用空間大小
uint64_t availableDisk = diskInfo.f_bavail * blocksize;
size = availableDisk;
}
return size;
}
//已用磁盤空間
- (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)ios_getSpaceForKey:(id)key {
NSError *error = nil;
NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:&error];
if (error) return -1;
int64_t space = [[attrs objectForKey:key] longLongValue];
if (space < 0) space = -1;
return space;
}
//磁盤號(hào)
- (NSNumber *)diskNumber {
NSDictionary *fattributes = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil];
return [fattributes objectForKey:NSFileSystemNumber];
}
//目錄下所有文件大小
- (int64_t)sizeOfDirectory:(NSString *)dir {
NSDirectoryEnumerator *direnum = [[NSFileManager defaultManager] enumeratorAtPath:dir];
NSString *pname;
int64_t s = 0;
while (pname = [direnum nextObject]){
NSDictionary *currentdict=[direnum fileAttributes];
NSString *filesize=[NSString stringWithFormat:@"%@",[currentdict objectForKey:NSFileSize]];
NSString *filetype=[currentdict objectForKey:NSFileType];
if([filetype isEqualToString:NSFileTypeDirectory]) continue;
s += [filesize longLongValue];
}
return s;
}
//將大小轉(zhuǎn)化為格式,B,L,M,G之間的轉(zhuǎn)換
- (NSString *)convertFloatSizeToString:(float)size {
if(size < 1024L) {
return [NSString stringWithFormat:@"%fB", size];
}else if(size < 1024L * 1024L) {
return [NSString stringWithFormat:@"%1.2fK", (float)size / 1024.0];
}else if(size < 1024L * 1024L * 1024L) {
return [NSString stringWithFormat:@"%1.2fM", (float)size / 1024.0 / 1024.0];
}else{
return [NSString stringWithFormat:@"%1.2fG", (float)size / 1024.0 / 1024.0 / 1024.0];
}
}
#pragma mark - ============== Memory ==============
//總內(nèi)存
- (int64_t)getTotalMemory {
int64_t totalMemory = [[NSProcessInfo processInfo] physicalMemory];
if (totalMemory < -1) totalMemory = -1;
return totalMemory;
}
- (float)c_totalMemory {
return [self sysInfo:HW_PHYSMEM];
//or
//return NSRealMemoryAvailable();
}
//活躍內(nèi)存
- (int64_t)getActiveMemory {
return [self ios_getMemoryWithType:MemoryTypeActive];
}
- (float)c_activeMemory {
return [self c_memoryWithType:MemoryTypeActive];
}
//不活躍內(nèi)存
- (int64_t)getInactiveMemory {
return [self ios_getMemoryWithType:MemoryTypeInactive];
}
- (float)c_inactiveMemory {
return [self c_memoryWithType:MemoryTypeInactive];
}
//剩余內(nèi)存
- (int64_t)getFreeMemory {
return [self ios_getMemoryWithType:MemoryTypeFree];
}
- (float)c_freeMemory {
return [self c_memoryWithType:MemoryTypeFree];
}
//用戶可使用內(nèi)存
- (float)c_userMemory {
return [self sysInfo:HW_USERMEM];
}
//已用內(nèi)存
- (int64_t)getUsedMemory {
return [self ios_getMemoryWithType:MemoryTypeUsed];
}
- (float)c_usedMemory {
return [self c_memoryWithType:MemoryTypeUsed];
}
//存放內(nèi)核和數(shù)據(jù)結(jié)構(gòu)的內(nèi)存
- (int64_t)getWiredMemory {
return [self ios_getMemoryWithType:MemoryTypeWired];
}
- (float)c_wireMemory {
return [self c_memoryWithType:MemoryTypeWired];
}
//可釋放的內(nèi)存
- (int64_t)getPurgeableMemory {
return [self ios_getMemoryWithType:MemoryTypePurgeable];
}
- (float)c_purgeableMemory {
return [self c_memoryWithType:MemoryTypePurgeable];
}
- (int64_t)ios_getMemoryWithType:(MemoryType)type{
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;
int64_t count = 0;
switch (type) {
case MemoryTypeFree:
count = vm_stat.free_count;
break;
case MemoryTypePurgeable:
count = vm_stat.purgeable_count;
break;
case MemoryTypeActive:
count = vm_stat.active_count;
break;
case MemoryTypeInactive:
count = vm_stat.inactive_count;
break;
case MemoryTypeWired:
count = vm_stat.wire_count;
break;
case MemoryTypeUsed:
count = vm_stat.active_count + vm_stat.inactive_count + vm_stat.wire_count;
break;
default:
break;
}
return count * page_size;
}
- (float)c_memoryWithType:(MemoryType)type{
vm_statistics_data_t vm_stat;
mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT;
kern_return_t kernReturn = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vm_stat, &infoCount);
if(kernReturn == KERN_SUCCESS){
int64_t count = 0;
switch (type) {
case MemoryTypeFree:
count = vm_stat.free_count;
break;
case MemoryTypePurgeable:
count = vm_stat.purgeable_count;
break;
case MemoryTypeActive:
count = vm_stat.active_count;
break;
case MemoryTypeInactive:
count = vm_stat.inactive_count;
break;
case MemoryTypeWired:
count = vm_stat.wire_count;
break;
case MemoryTypeUsed:
count = vm_stat.active_count + vm_stat.inactive_count + vm_stat.wire_count;
break;
default:
break;
}
return count * vm_page_size * 1.0;
}
return -1;
}
//CPU使用頻率
- (float)cpuFrequency{
return [self sysInfo:HW_CPU_FREQ];
}
//CPU總線頻率
- (float)busFrequency{
return [self sysInfo:HW_BUS_FREQ];
}
//最大Socket緩存區(qū)大小
- (float)maxSocketBufferSize{
return [self sysInfo:KIPC_MAXSOCKBUF];
}
- (float)sysInfo:(uint)typeSpecifier{
size_t size = sizeof(int);
int results;
int mib[2] = {CTL_HW, typeSpecifier};
sysctl(mib, 2, &results, &size, NULL, 0);
return (NSUInteger) results * 1.0;
}
@end