【iOS】獲取設(shè)備信息

在項(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

歡迎補(bǔ)充~~
https://github.com/idbeny/YBDeviceManager.git

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容