SystemServices 库源码分析(获取设备信息)(3)

SSCarrierInfo

获取网络相关信息

// Carrier Name
+ (NSString *)carrierName {
    // Get the carrier name
    @try {
        // Get the Telephony Network Info
        CTTelephonyNetworkInfo *telephonyInfo = [[CTTelephonyNetworkInfo alloc] init];
        // Get the carrier
        CTCarrier *carrier = [telephonyInfo subscriberCellularProvider];
        // Get the carrier name
        NSString *carrierName = [carrier carrierName];
        
        // Check to make sure it's valid
        if (carrierName == nil || carrierName.length <= 0) {
            // Return unknown
            return nil;
        }
        
        // Return the name
        return carrierName;
    }
    @catch (NSException *exception) {
        // Error finding the name
        return nil;
    }
}

获取网络运营商的名字 。比如“中国移动,中国联通”

+ (NSString *)carrierCountry {
    // Get the country that the carrier is located in
    @try {
        // Get the locale
        NSLocale *currentCountry = [NSLocale currentLocale];
        // Get the country Code
        NSString *country = [currentCountry objectForKey:NSLocaleCountryCode];
        // Check if it returned anything
        if (country == nil || country.length <= 0) {
            // No country found
            return nil;
        }
        // Return the country
        return country;
    }
    @catch (NSException *exception) {
        // Failed, return nil
        return nil;
    }
}

获取国家的代号 比如“CN”

// Carrier Mobile Country Code
+ (NSString *)carrierMobileCountryCode {
    // Get the carrier mobile country code
    @try {
        // Get the Telephony Network Info
        CTTelephonyNetworkInfo *telephonyInfo = [[CTTelephonyNetworkInfo alloc] init];
        // Get the carrier
        CTCarrier *carrier = [telephonyInfo subscriberCellularProvider];
        // Get the carrier mobile country code
        NSString *carrierCode = [carrier mobileCountryCode];
        
        // Check to make sure it's valid
        if (carrierCode == nil || carrierCode.length <= 0) {
            // Return unknown
            return nil;
        }
        
        // Return the name
        return carrierCode;
    }
    @catch (NSException *exception) {
        // Error finding the name
        return nil;
    }
}

获取手机 国家代号 eg :460

// Carrier ISO Country Code
+ (NSString *)carrierISOCountryCode {
    // Get the carrier ISO country code
    @try {
        // Get the Telephony Network Info
        CTTelephonyNetworkInfo *telephonyInfo = [[CTTelephonyNetworkInfo alloc] init];
        // Get the carrier
        CTCarrier *carrier = [telephonyInfo subscriberCellularProvider];
        // Get the carrier ISO country code
        NSString *carrierCode = [carrier isoCountryCode];
        
        // Check to make sure it's valid
        if (carrierCode == nil || carrierCode.length <= 0) {
            // Return unknown
            return nil;
        }
        
        // Return the name
        return carrierCode;
    }
    @catch (NSException *exception) {
        // Error finding the name
        return nil;
    }
}

获取 IOS 国家代号

// Carrier Mobile Network Code
+ (NSString *)carrierMobileNetworkCode {
    // Get the carrier mobile network code
    @try {
        // Get the Telephony Network Info
        CTTelephonyNetworkInfo *telephonyInfo = [[CTTelephonyNetworkInfo alloc] init];
        // Get the carrier
        CTCarrier *carrier = [telephonyInfo subscriberCellularProvider];
        // Get the carrier mobile network code
        NSString *carrierCode = [carrier mobileNetworkCode];
        
        // Check to make sure it's valid
        if (carrierCode == nil || carrierCode.length <= 0) {
            // Return unknown
            return nil;
        }
        
        // Return the name
        return carrierCode;
    }
    @catch (NSException *exception) {
        // Error finding the name
        return nil;
    }
}

获取手机网络代号

// Carrier Allows VOIP
+ (BOOL)carrierAllowsVOIP {
    // Check if the carrier allows VOIP
    @try {
        // Get the Telephony Network Info
        CTTelephonyNetworkInfo *telephonyInfo = [[CTTelephonyNetworkInfo alloc] init];
        // Get the carrier
        CTCarrier *carrier = [telephonyInfo subscriberCellularProvider];
        // Get the carrier VOIP Status
        BOOL carrierVOIP = [carrier allowsVOIP];
        
        // Return the VOIP Status
        return carrierVOIP;
    }
    @catch (NSException *exception) {
        // Error finding the VOIP Status
        return false;
    }
}

是否允许 voIp。

SSBatteryInfo

电池相关

// Battery Level
+ (float)batteryLevel {
    // Find the battery level
    @try {
        // Get the device
        UIDevice *device = [UIDevice currentDevice];
        // Set battery monitoring on
        device.batteryMonitoringEnabled = YES;
        
        // Set up the battery level float
        float batteryLevel = 0.0;
        // Get the battery level
        float batteryCharge = [device batteryLevel];
        
        // Check to make sure the battery level is more than zero
        if (batteryCharge > 0.0f) {
            // Make the battery level float equal to the charge * 100
            batteryLevel = batteryCharge * 100;
        } else {
            // Unable to find the battery level
            return -1;
        }
        
        // Output the battery level
        return batteryLevel;
    }
    @catch (NSException *exception) {
        // Error out
        return -1;
    }
}

获取剩余电量

// Charging?
+ (BOOL)charging {
    // Is the battery charging?
    @try {
        // Get the device
        UIDevice *device = [UIDevice currentDevice];
        // Set battery monitoring on
        device.batteryMonitoringEnabled = YES;
        
        // Check the battery state
        if ([device batteryState] == UIDeviceBatteryStateCharging || [device batteryState] == UIDeviceBatteryStateFull) {
            // Device is charging
            return true;
        } else {
            // Device is not charging
            return false;
        }
    }
    @catch (NSException *exception) {
        // Error out
        return false;
    }
}

是否正在充电

// Fully Charged?
+ (BOOL)fullyCharged {
    // Is the battery fully charged?
    @try {
        // Get the device
        UIDevice *device = [UIDevice currentDevice];
        // Set battery monitoring on
        device.batteryMonitoringEnabled = YES;
        
        // Check the battery state
        if ([device batteryState] == UIDeviceBatteryStateFull) {
            // Device is fully charged
            return true;
        } else {
            // Device is not fully charged
            return false;
        }
    }
    @catch (NSException *exception) {
        // Error out
        return false;
    }
}

是否已经充满电了

SSNetworkInfo

网络IP信息

// Get WiFi IP Address
+ (nullable NSString *)wiFiIPAddress {
    // Get the WiFi IP Address
    @try {
        // Set a string for the address
        NSString *ipAddress;
        // Set up structs to hold the interfaces and the temporary address
        struct ifaddrs *interfaces;
        struct ifaddrs *temp;
        // Set up int for success or fail
        int Status = 0;
        
        // Get all the network interfaces
        Status = getifaddrs(&interfaces);
        
        // If it's 0, then it's good
        if (Status == 0)
        {
            // Loop through the list of interfaces
            temp = interfaces;
            
            // Run through it while it's still available
            while(temp != NULL)
            {
                // If the temp interface is a valid interface
                if(temp->ifa_addr->sa_family == AF_INET)
                {
                    // Check if the interface is WiFi
                    if([[NSString stringWithUTF8String:temp->ifa_name] isEqualToString:@"en0"])
                    {
                        // Get the WiFi IP Address
                        ipAddress = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp->ifa_addr)->sin_addr)];
                    }
                }
                
                // Set the temp value to the next interface
                temp = temp->ifa_next;
            }
        }
        
        // Free the memory of the interfaces
        freeifaddrs(interfaces);
        
        // Check to make sure it's not empty
        if (ipAddress == nil || ipAddress.length <= 0) {
            // Empty, return not found
            return nil;
        }
        
        // Return the IP Address of the WiFi
        return ipAddress;
    }
    @catch (NSException *exception) {
        // Error, IP Not found
        return nil;
    }
}

获取wifi ip地址

+ (BOOL)connectedToWiFi {
    // Check if we're connected to WiFi
    NSString *wiFiAddress = [self wiFiIPAddress];
    // Check if the string is populated
    if (wiFiAddress == nil || wiFiAddress.length <= 0) {
        // Nothing found
        return false;
    } else {
        // WiFi in use
        return true;
    }
}

是否连接wifi

// Get Cell IP Address
+ (nullable NSString *)cellIPAddress {
    // Get the Cell IP Address
    @try {
        // Set a string for the address
        NSString *ipAddress;
        // Set up structs to hold the interfaces and the temporary address
        struct ifaddrs *interfaces;
        struct ifaddrs *temp;
        struct sockaddr_in *s4;
        char buf[64];
        
        // If it's 0, then it's good
        if (!getifaddrs(&interfaces))
        {
            // Loop through the list of interfaces
            temp = interfaces;
            
            // Run through it while it's still available
            while(temp != NULL)
            {
                // If the temp interface is a valid interface
                if(temp->ifa_addr->sa_family == AF_INET)
                {
                    // Check if the interface is Cell
                    if([[NSString stringWithUTF8String:temp->ifa_name] isEqualToString:@"pdp_ip0"])
                    {
                        s4 = (struct sockaddr_in *)temp->ifa_addr;
                        
                        if (inet_ntop(temp->ifa_addr->sa_family, (void *)&(s4->sin_addr), buf, sizeof(buf)) == NULL) {
                            // Failed to find it
                            ipAddress = nil;
                        } else {
                            // Got the Cell IP Address
                            ipAddress = [NSString stringWithUTF8String:buf];
                        }
                    }
                }
                
                // Set the temp value to the next interface
                temp = temp->ifa_next;
            }
        }
        
        // Free the memory of the interfaces
        freeifaddrs(interfaces);
        
        // Check to make sure it's not empty
        if (ipAddress == nil || ipAddress.length <= 0) {
            // Empty, return not found
            return nil;
        }
        
        // Return the IP Address of the WiFi
        return ipAddress;
    }
    @catch (NSException *exception) {
        // Error, IP Not found
        return nil;
    }
}

获取cell 地址

define IOS_CELLULAR @"pdp_ip0"

define IOS_WIFI @"en0"

define IOS_VPN @"utun0"

define IP_ADDR_IPv4 @"ipv4"

define IP_ADDR_IPv6 @"ipv6"

// Connected to Cellular Network?
+ (BOOL)connectedToCellNetwork {
    // Check if we're connected to cell network
    NSString *cellAddress = [self cellIPAddress];
    // Check if the string is populated
    if (cellAddress == nil || cellAddress.length <= 0) {
        // Nothing found
        return false;
    } else {
        // Cellular Network in use
        return true;
    }
}

是否连接cell网络

// Get Current IP Address
+ (nullable NSString *)currentIPAddress {
    // Get the current IP Address
    
    // Check which interface is currently in use
    if ([self connectedToWiFi]) {
        // WiFi is in use
        
        // Get the WiFi IP Address
        NSString *wiFiAddress = [self wiFiIPAddress];
        
        // Check that you get something back
        if (wiFiAddress == nil || wiFiAddress.length <= 0) {
            // Error, no address found
            return nil;
        }
        
        // Return Wifi address
        return wiFiAddress;
    } else if ([self connectedToCellNetwork]) {
        // Cell Network is in use
        
        // Get the Cell IP Address
        NSString *cellAddress = [self cellIPAddress];
        
        // Check that you get something back
        if (cellAddress == nil || cellAddress.length <= 0) {
            // Error, no address found
            return nil;
        }
        
        // Return Cell address
        return cellAddress;
    } else {
        // No interface in use
        return nil;
    }
}

获取当前IP 地址,这里我们应该知道,手机连接wifi 和 cell网络的时候,默认是使用wifi网络。

// Get the External IP Address
+ (nullable NSString *)externalIPAddress {
    @try {
        // Check if we have an internet connection then try to get the External IP Address
        if (![self connectedToCellNetwork] && ![self connectedToWiFi]) {
            // Not connected to anything, return nil
            return nil;
        }
        
        // Get the external IP Address based on icanhazip.com
        NSError *error = nil;
        
        // Using https://icanhazip.com
        NSString *externalIP = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"https://icanhazip.com/"] encoding:NSUTF8StringEncoding error:&error];
        
        if (!error) {
            
            // Format the IP Address
            externalIP = [externalIP stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
            
            // Check that you get something back
            if (externalIP == nil || externalIP.length <= 0) {
                // Error, no address found
                return nil;
            }
            
            // Return External IP
            return externalIP;
        } else {
            // Error, no address found
            return nil;
        }
    }
    @catch (NSException *exception) {
        // Error, no address found
        return nil;
    }
}

获取ip地址。这个是通过https://icanhazip.com/,将地址返回的

// Get Cell IPv6 Address
+ (nullable NSString *)cellIPv6Address {
    // Get the Cell IP Address
    @try {
        // Set a string for the address
        NSString *ipAddress;
        // Set up structs to hold the interfaces and the temporary address
        struct ifaddrs *interfaces;
        struct ifaddrs *temp;
        struct sockaddr_in6 *s6;
        char buf[INET6_ADDRSTRLEN];
        
        // If it's 0, then it's good
        if (!getifaddrs(&interfaces))
        {
            // Loop through the list of interfaces
            temp = interfaces;
            
            // Run through it while it's still available
            while(temp != NULL)
            {
                // If the temp interface is a valid interface
                if(temp->ifa_addr->sa_family == AF_INET6)
                {
                    // Check if the interface is Cell
                    if([[NSString stringWithUTF8String:temp->ifa_name] isEqualToString:@"pdp_ip0"])
                    {
                        s6 = (struct sockaddr_in6 *)temp->ifa_addr;
                        
                        if (inet_ntop(AF_INET6, (void *)&(s6->sin6_addr), buf, sizeof(buf)) == NULL) {
                            // Failed to find it
                            ipAddress = nil;
                        } else {
                            // Got the Cell IP Address
                            ipAddress = [NSString stringWithUTF8String:buf];
                        }
                    }
                }
                
                // Set the temp value to the next interface
                temp = temp->ifa_next;
            }
        }
        
        // Free the memory of the interfaces
        freeifaddrs(interfaces);
        
        // Check to make sure it's not empty
        if (ipAddress == nil || ipAddress.length <= 0) {
            // Empty, return not found
            return nil;
        }
        
        // Return the IP Address of the WiFi
        return ipAddress;
    }
    @catch (NSException *exception) {
        // Error, IP Not found
        return nil;
    }
}

获取ipv6 的cell 地址,不过这里作者没有调用key

// Get Cell Netmask Address
+ (nullable NSString *)cellNetmaskAddress {
    // Get the Cell Netmask Address
    @try {
        // Set up the variable
        struct ifreq afr;
        // Copy the string
        strncpy(afr.ifr_name, [@"pdp_ip0" UTF8String], IFNAMSIZ-1);
        // Open a socket
        int afd = socket(AF_INET, SOCK_DGRAM, 0);
        
        // Check the socket
        if (afd == -1) {
            // Error, socket failed to open
            return nil;
        }
        
        // Check the netmask output
        if (ioctl(afd, SIOCGIFNETMASK, &afr) == -1) {
            // Error, netmask wasn't found
            // Close the socket
            close(afd);
            // Return error
            return nil;
        }
        
        // Close the socket
        close(afd);
        
        // Create a char for the netmask
        char *netstring = inet_ntoa(((struct sockaddr_in *)&afr.ifr_addr)->sin_addr);
        
        // Create a string for the netmask
        NSString *Netmask = [NSString stringWithUTF8String:netstring];
        
        // Check to make sure it's not nil
        if (Netmask == nil || Netmask.length <= 0) {
            // Error, netmask not found
            return nil;
        }
        
        // Return successful
        return Netmask;
    }
    @catch (NSException *exception) {
        // Error
        return nil;
    }
}

获取cell 的mask。子网掩码

// Get Cell Broadcast Address
+ (nullable NSString *)cellBroadcastAddress {
    // Get the Cell Broadcast Address
    @try {
        // Set up strings for the IP and Netmask
        NSString *ipAddress = [self cellIPAddress];
        NSString *nmAddress = [self cellNetmaskAddress];
        
        // Check to make sure they aren't nil
        if (ipAddress == nil || ipAddress.length <= 0) {
            // Error, IP Address can't be nil
            return nil;
        }
        if (nmAddress == nil || nmAddress.length <= 0) {
            // Error, NM Address can't be nil
            return nil;
        }
        
        // Check the formatting of the IP and NM Addresses
        NSArray *ipCheck = [ipAddress componentsSeparatedByString:@"."];
        NSArray *nmCheck = [nmAddress componentsSeparatedByString:@"."];
        
        // Make sure the IP and NM Addresses are correct
        if (ipCheck.count != 4 || nmCheck.count != 4) {
            // Incorrect IP Addresses
            return nil;
        }
        
        // Set up the variables
        NSUInteger ip = 0;
        NSUInteger nm = 0;
        NSUInteger cs = 24;
        
        // Make the address based on the other addresses
        for (NSUInteger i = 0; i < 4; i++, cs -= 8) {
            ip |= [[ipCheck objectAtIndex:i] intValue] << cs;
            nm |= [[nmCheck objectAtIndex:i] intValue] << cs;
        }
        
        // Set it equal to the formatted raw addresses
        NSUInteger ba = ~nm | ip;
        
        // Make a string for the address
        NSString *broadcastAddress = [NSString stringWithFormat:@"%ld.%ld.%ld.%ld", (long)(ba & 0xFF000000) >> 24,
                                      (long)(ba & 0x00FF0000) >> 16, (long)(ba & 0x0000FF00) >> 8, (long)(ba & 0x000000FF)];
        
        // Check to make sure the string is valid
        if (broadcastAddress == nil || broadcastAddress.length <= 0) {
            // Error, no address
            return nil;
        }
        
        // Return Successful
        return broadcastAddress;
    }
    @catch (NSException *exception) {
        // Error
        return nil;
    }
}

获取网络的广播地址
广播地址计算方式

网络中主机位全为1即为广播地址,如网段为192.168(子网掩码255.255.0.0),则广播地址为192.168.255.255,网段为192.168.0(子网掩码255.255.255.0),则广播地址为192.168.0.255.标准的做法是先判断192属于那一类地址。再设置相应的掩码和广播地址。(只要用主机的IP地址与子网掩码进行与运算即可知道该主机属于哪一个广播域。)

// Get WiFi IPv6 Address
+ (nullable NSString *)wiFiIPv6Address {
    // Get the WiFi IP Address
    @try {
        // Set a string for the address
        NSString *ipAddress;
        // Set up structs to hold the interfaces and the temporary address
        struct ifaddrs *interfaces;
        struct ifaddrs *temp;
        // Set up int for success or fail
        int status = 0;
        
        // Get all the network interfaces
        status = getifaddrs(&interfaces);
        
        // If it's 0, then it's good
        if (status == 0)
        {
            // Loop through the list of interfaces
            temp = interfaces;
            
            // Run through it while it's still available
            while(temp != NULL)
            {
                // If the temp interface is a valid interface
                if(temp->ifa_addr->sa_family == AF_INET6)
                {
                    // Check if the interface is WiFi
                    if([[NSString stringWithUTF8String:temp->ifa_name] isEqualToString:@"en0"])
                    {
                        // Get the WiFi IP Address
                        struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)temp->ifa_addr;
                        char buf[INET6_ADDRSTRLEN];
                        if (inet_ntop(AF_INET6, (void *)&(addr6->sin6_addr), buf, sizeof(buf)) == NULL) {
                            // Failed to find it
                            ipAddress = nil;
                        } else {
                            // Got the Cell IP Address
                            ipAddress = [NSString stringWithUTF8String:buf];
                        }
                    }
                }
                
                // Set the temp value to the next interface
                temp = temp->ifa_next;
            }
        }
        
        // Free the memory of the interfaces
        freeifaddrs(interfaces);
        
        // Check to make sure it's not empty
        if (ipAddress == nil || ipAddress.length <= 0) {
            // Empty, return not found
            return nil;
        }
        
        // Return the IP Address of the WiFi
        return ipAddress;
    }
    @catch (NSException *exception) {
        // Error, IP Not found
        return nil;
    }
}

获取wifi ipv6 地址

// Get WiFi Netmask Address
+ (nullable NSString *)wiFiNetmaskAddress {
    // Get the WiFi Netmask Address
    @try {
        // Set up the variable
        struct ifreq afr;
        // Copy the string
        strncpy(afr.ifr_name, [@"en0" UTF8String], IFNAMSIZ-1);
        // Open a socket
        int afd = socket(AF_INET, SOCK_DGRAM, 0);
        
        // Check the socket
        if (afd == -1) {
            // Error, socket failed to open
            return nil;
        }
        
        // Check the netmask output
        if (ioctl(afd, SIOCGIFNETMASK, &afr) == -1) {
            // Error, netmask wasn't found
            // Close the socket
            close(afd);
            // Return error
            return nil;
        }
        
        // Close the socket
        close(afd);
        
        // Create a char for the netmask
        char *netstring = inet_ntoa(((struct sockaddr_in *)&afr.ifr_addr)->sin_addr);
        
        // Create a string for the netmask
        NSString *netmask = [NSString stringWithUTF8String:netstring];
        
        // Check to make sure it's not nil
        if (netmask == nil || netmask.length <= 0) {
            // Error, netmask not found
            return nil;
        }
        
        // Return successful
        return netmask;
    }
    @catch (NSException *exception) {
        // Error
        return nil;
    }
}

wifi 子网掩码

// Get WiFi Broadcast Address
+ (nullable NSString *)wiFiBroadcastAddress {
    // Get the WiFi Broadcast Address
    @try {
        // Set up strings for the IP and Netmask
        NSString *ipAddress = [self wiFiIPAddress];
        NSString *nmAddress = [self wiFiNetmaskAddress];
        
        // Check to make sure they aren't nil
        if (ipAddress == nil || ipAddress.length <= 0) {
            // Error, IP Address can't be nil
            return nil;
        }
        if (nmAddress == nil || nmAddress.length <= 0) {
            // Error, NM Address can't be nil
            return nil;
        }
        
        // Check the formatting of the IP and NM Addresses
        NSArray *ipCheck = [ipAddress componentsSeparatedByString:@"."];
        NSArray *nmCheck = [nmAddress componentsSeparatedByString:@"."];
        
        // Make sure the IP and NM Addresses are correct
        if (ipCheck.count != 4 || nmCheck.count != 4) {
            // Incorrect IP Addresses
            return nil;
        }
        
        // Set up the variables
        NSUInteger ip = 0;
        NSUInteger nm = 0;
        NSUInteger cs = 24;
        
        // Make the address based on the other addresses
        for (NSUInteger i = 0; i < 4; i++, cs -= 8) {
            ip |= [[ipCheck objectAtIndex:i] intValue] << cs;
            nm |= [[nmCheck objectAtIndex:i] intValue] << cs;
        }
        
        // Set it equal to the formatted raw addresses
        NSUInteger ba = ~nm | ip;
        
        // Make a string for the address
        NSString *broadcastAddress = [NSString stringWithFormat:@"%lu.%lu.%lu.%lu", (long)(ba & 0xFF000000) >> 24,
                                      (long)(ba & 0x00FF0000) >> 16, (long)(ba & 0x0000FF00) >> 8, (long)(ba & 0x000000FF)];
        
        // Check to make sure the string is valid
        if (broadcastAddress == nil || broadcastAddress.length <= 0) {
            // Error, no address
            return nil;
        }
        
        // Return Successful
        return broadcastAddress;
    }
    @catch (NSException *exception) {
        // Error
        return nil;
    }
}

wifi 广播

+ (nullable NSString *)wiFiRouterAddress {
    // Get the WiFi Router Address
    @try {
        // Set the ip address variable
        NSString *routerIP = nil;
        // Set the router array variable with the routing information
        NSMutableArray *routerArray = [Route_Info getRoutes];
        // Run through the array
        for(int i = 0; i < (int)[routerArray count]; i++)
        {
            // Set the router info
            Route_Info* router = (Route_Info*)[routerArray objectAtIndex:i];
            routerIP = [router getGateway];
        }
        // Return Successful
        return routerIP;
    }
    @catch (NSException *exception) {
        // Error
        return nil;
    }
}

获取路由地址

sysctl() 函数介绍

int sysctl( int *name, u_int namelen, void *oldp, size_t *oldenp, void *newp, size_t newlen );
返回0:成功 -1:失败

name参数是指定名字的一个整数数组,namelen参数指定了该数组中的元素数目。该数组中的第一个元素指定本请求定向到内核的哪个子系统。第二个及其后元素依次细化指定该系
统的某个部分。
为了获取某个值,oldp参数指向一个供内核存放该值的缓冲区。oldlenp则是一个值-结果参数:函数被调用时,oldlenp指向的值指定该缓冲区的大小;函数返回时,该值给出内核存
放在该缓冲区中的数据量。如果这个缓冲不够大,函数就返回ENOMEM错误。作为特例,Oldp可以是一个空指针,而oldlenp却是一个非空指针,内核确定这样的调用应该返回的数据量,并通过oldlenp返回这个大小。
为了设置某个新值,newp参数指向一个大小为newlen参数值的缓冲区。如果不准备指定一个新值,那么newp应为一个空指针,newlen因为0.

sysctl的man手册详细叙述了该函数可以获取的各种系统消息,有文件系统,虚拟内存,内核限制,硬件等各个方面的信息。我们感兴趣的是网络子系统,通过把name数组的第一个元素设置成CTL_NET来指定。(CTL_XXX常值在中定义),第二个元素可以:

 > AF_INET:  获取或者设置影响网际协议的变量。下一级为使用某个IPPROTO_XXX常

值指定的具体协议。
> AF_LINK: 获取或设置链路层信息,例如:PPP接口的数目。

AF_ROUTE:  返回路由表或接口清单的信息。

AF_UNSPEC: 获取或设置一些套接口层变量,例如套接口发送或接收缓冲区的最大大小

当name数组的第二个元素为AF_ROUTE时,第三个元素(协议号)总是为0,第四个元素
是一个地址族,第五个和第六个指定做什么,如下表所示:

SystemServices 库源码分析(获取设备信息)(3)_第1张图片
image.png

路由域支持三种操作,由name[4]指定。(NET_RT_xxx常值在中定义),这三种操作返回的信息通过sysctl调用中的oldp指针返回。Oldp指向的缓冲区中含有可变数目的RTM_xxx消息。

1 NET_RT_DUMP返回由name[3]指定的地址族的路由表。如果所指定的地址族为0,那么返回所有地址族的路由表。
路由表作为可变数目的RTM_GET消息返回,每个消息后跟最多4个套接口地址结构:
本路由表项目的地址,网关,网络掩码和克隆掩码。相比直接读写路由套接口操作,sysctl操作所有改动仅仅体现在内核通过后者返回一个或者多个RTM_GET消息。

2 NET_RT_FLAGS返回由name[3]指定的地址族的路由表,但是仅仅限于那些所带标志(若干个RTF_XXX常值的逻辑或)与由name[5]指定的标志匹配的路由表项。路由表中所有ARP高速缓存均设置了RTF_LLINFO标志位。这种操作的信息返回格式和上一
种操作的一致。

3 NET_RT_IFLIST返回所有已配置接口的信息。如果name[5]不为0,它就是某个接口的索引,于是仅仅返回该接口的信息。已赋予每个接口的所有地址也同时返回。不过如果name[3]不为0,那么仅限于返回指定地址族的地址。

SSProcessInfo

获取进程id

+ (int)processID {
    // Get the Process ID
    @try {
        // Get the PID
        int pid = getpid();
        // Make sure it's correct
        if (pid <= 0) {
            // Incorrect PID
            return -1;
        }
        // Successful
        return pid;
    }
    @catch (NSException *exception) {
        // Error
        return -1;
    }
}

SSMemoryInfo

内存信息


// Total Memory
+ (double)totalMemory {
    // Find the total amount of memory  
    @try {
        // Set up the variables
        double totalMemory = 0.00;
        double allMemory = [[NSProcessInfo processInfo] physicalMemory];
        
        // Total Memory (formatted)
        totalMemory = (allMemory / 1024.0) / 1024.0;
        
        // Round to the nearest multiple of 256mb - Almost all RAM is a multiple of 256mb (I do believe)
        int toNearest = 256;
        int remainder = (int)totalMemory % toNearest;
        
        if (remainder >= toNearest / 2) {
            // Round the final number up
            totalMemory = ((int)totalMemory - remainder) + 256;
        } else {
            // Round the final number down
            totalMemory = (int)totalMemory - remainder;
        }
        
        // Check to make sure it's valid
        if (totalMemory <= 0) {
            // Error, invalid memory value
            return -1;
        }
        
        // Completed Successfully
        return totalMemory;
    }
    @catch (NSException *exception) {
        // Error
        return -1;
    }
}

获取内存大小

// Free Memory
+ (double)freeMemory:(BOOL)inPercent {
    // Find the total amount of free memory
    @try {
        // Set up the variables
        double totalMemory = 0.00;
        vm_statistics_data_t vmStats;
        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)&vmStats, &infoCount);
        
        if(kernReturn != KERN_SUCCESS) {
            return -1;
        }
        
        // Check if the user wants it in percent
        if (inPercent) {
            // Percent
            // Convert to doubles
            double fm = [self totalMemory];
            double am = ((vm_page_size * vmStats.free_count) / 1024.0) / 1024.0;
            // Get the percent
            totalMemory = (am * 100) / fm;
        } else {
            // Not in percent
            // Total Memory (formatted)
            totalMemory = ((vm_page_size * vmStats.free_count) / 1024.0) / 1024.0;
        }
        
        // Check to make sure it's valid
        if (totalMemory <= 0) {
            // Error, invalid memory value
            return -1;
        }
        
        // Completed Successfully
        return totalMemory;
    }
    @catch (NSException *exception) {
        // Error
        return -1;
    }
}

剩余内存大小

// Used Memory
+ (double)usedMemory:(BOOL)inPercent {
    // Find the total amount of used memory
    @try {
        // Set up the variables
        double totalUsedMemory = 0.00;
        mach_port_t host_port;
        mach_msg_type_number_t host_size;
        vm_size_t pagesize;
        
        // Get the variable values
        host_port = mach_host_self();
        host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
        host_page_size(host_port, &pagesize);
        
        vm_statistics_data_t vm_stat;
        
        // Check for any system errors
        if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
            // Error, failed to get Virtual memory info
            return -1;
        }
        
        // Memory statistics in bytes
        natural_t usedMemory = (natural_t)((vm_stat.active_count +
                                vm_stat.inactive_count +
                                vm_stat.wire_count) * pagesize);
        natural_t allMemory = [self totalMemory];
        
        // Check if the user wants it in percent
        if (inPercent) {
            // Percent
            // Convert to doubles
            double um = (usedMemory /1024) / 1024;
            double am = allMemory;
            // Get the percent
            totalUsedMemory = (um * 100) / am;
        } else {
            // Not in percent
            // Total Used Memory (formatted)
            totalUsedMemory = (usedMemory / 1024.0) / 1024.0;
        }
        
        // Check to make sure it's valid
        if (totalUsedMemory <= 0) {
            // Error, invalid memory value
            return -1;
        }
        
        // Completed Successfully
        return totalUsedMemory;
    }
    @catch (NSException *exception) {
        // Error
        return -1;
    }
}

已经使用内存


// Active Memory
+ (double)activeMemory:(BOOL)inPercent {
    // Find the Active memory
    @try {
        // Set up the variables
        double totalMemory = 0.00;
        mach_port_t host_port;
        mach_msg_type_number_t host_size;
        vm_size_t pagesize;
        
        // Get the variable values
        host_port = mach_host_self();
        host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
        host_page_size(host_port, &pagesize);
        
        vm_statistics_data_t vm_stat;
        
        // Check for any system errors
        if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
            // Error, failed to get Virtual memory info
            return -1;
        }
        
        // Check if the user wants it in percent
        if (inPercent) {
            // Percent
            // Convert to doubles
            double FM = [self totalMemory];
            double AM = ((vm_stat.active_count * pagesize) / 1024.0) / 1024.0;
            // Get the percent
            totalMemory = (AM * 100) / FM;
        } else {
            // Not in percent
            // Total Memory (formatted)
            totalMemory = ((vm_stat.active_count * pagesize) / 1024.0) / 1024.0;
        }
        
        // Check to make sure it's valid
        if (totalMemory <= 0) {
            // Error, invalid memory value
            return -1;
        }
        
        // Completed Successfully
        return totalMemory;
    }
    @catch (NSException *exception) {
        // Error
        return -1;
    }
}

活跃内存

// Inactive Memory
+ (double)inactiveMemory:(BOOL)inPercent {
    // Find the Inactive memory
    @try {
        // Set up the variables
        double totalMemory = 0.00;
        mach_port_t host_port;
        mach_msg_type_number_t host_size;
        vm_size_t pagesize;
        
        // Get the variable values
        host_port = mach_host_self();
        host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
        host_page_size(host_port, &pagesize);
        
        vm_statistics_data_t vm_stat;
        
        // Check for any system errors
        if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
            // Error, failed to get Virtual memory info
            return -1;
        }
        
        // Check if the user wants it in percent
        if (inPercent) {
            // Percent
            // Convert to doubles
            double FM = [self totalMemory];
            double AM = ((vm_stat.inactive_count * pagesize) / 1024.0) / 1024.0;
            // Get the percent
            totalMemory = (AM * 100) / FM;
        } else {
            // Not in percent
            // Total Memory (formatted)
            totalMemory = ((vm_stat.inactive_count * pagesize) / 1024.0) / 1024.0;
        }
        
        // Check to make sure it's valid
        if (totalMemory <= 0) {
            // Error, invalid memory value
            return -1;
        }
        
        // Completed Successfully
        return totalMemory;
    }
    @catch (NSException *exception) {
        // Error
        return -1;
    }
}

待用内存

// Wired Memory
+ (double)wiredMemory:(BOOL)inPercent {
    // Find the Wired memory
    @try {
        // Set up the variables
        double totalMemory = 0.00;
        mach_port_t host_port;
        mach_msg_type_number_t host_size;
        vm_size_t pagesize;
        
        // Get the variable values
        host_port = mach_host_self();
        host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
        host_page_size(host_port, &pagesize);
        
        vm_statistics_data_t vm_stat;
        
        // Check for any system errors
        if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
            // Error, failed to get Virtual memory info
            return -1;
        }
        
        // Check if the user wants it in percent
        if (inPercent) {
            // Percent
            // Convert to doubles
            double FM = [self totalMemory];
            double AM = ((vm_stat.wire_count * pagesize) / 1024.0) / 1024.0;
            // Get the percent
            totalMemory = (AM * 100) / FM;
        } else {
            // Not in percent
            // Total Memory (formatted)
            totalMemory = ((vm_stat.wire_count * pagesize) / 1024.0) / 1024.0;
        }
        
        // Check to make sure it's valid
        if (totalMemory <= 0) {
            // Error, invalid memory value
            return -1;
        }
        
        // Completed Successfully
        return totalMemory;
    }
    @catch (NSException *exception) {
        // Error
        return -1;
    }
}

联动内存

// Purgable Memory
+ (double)purgableMemory:(BOOL)inPercent {
    // Find the Purgable memory
    @try {
        // Set up the variables
        double totalMemory = 0.00;
        mach_port_t host_port;
        mach_msg_type_number_t host_size;
        vm_size_t pagesize;
        
        // Get the variable values
        host_port = mach_host_self();
        host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
        host_page_size(host_port, &pagesize);
        
        vm_statistics_data_t vm_stat;
        
        // Check for any system errors
        if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
            // Error, failed to get Virtual memory info
            return -1;
        }
        
        // Check if the user wants it in percent
        if (inPercent) {
            // Percent
            // Convert to doubles
            double fm = [self totalMemory];
            double am = ((vm_stat.purgeable_count * pagesize) / 1024.0) / 1024.0;
            // Get the percent
            totalMemory = (am * 100) / fm;
        } else {
            // Not in percent
            // Total Memory (formatted)
            totalMemory = ((vm_stat.purgeable_count * pagesize) / 1024.0) / 1024.0;
        }
        
        // Check to make sure it's valid
        if (totalMemory <= 0) {
            // Error, invalid memory value
            return -1;
        }
        
        // Completed Successfully
        return totalMemory;
    }
    @catch (NSException *exception) {
        // Error
        return -1;
    }
}

获取 Purgable 内存 (可清除内存)

这里我们应该弄清楚几个概念

Wired memory: 系统核心占用的,永远不会从系统物【[内存】中驱除。
Active(活跃): 表示这些内存数据正在使用种,或者刚被使用过。
Inactive(非活跃): 表示这些内存中的数据是有效的,但是最近没有被使用。
Free(可用空间): 表示这些内存中的数据是无效的,即内存剩余量!

当Free的【内存】低于某个key值时
这个key值是由你的物理内存大小决定的,系统则会按照以下顺序使用Inactive的资源。

◇首先,如果Inactive的数据最近被调用了,系统会把它们的状态改变成Active,并且在原有Active内存逻辑地址的后面;

◇其次,如果Inactive的内存数据最近没有被使用过,但是曾经被更改过,而还没有在硬盘的相应虚拟[内存]中做修改,系统会对相应硬盘的虚拟内存做修改,并把这部分物理内存释放为free供程序使用。

◇再次,如果inactive[内存]中得数据被在映射到硬盘后再没有被更改过,则直接释放成free。

◇最后如果active的内存一段时间没有被使用,会被暂时改变状态为inactive。

所以,如果你的系统里有少量的free memeory和大量的inactive的memeory,说明你的内存是够用的,系统运行在最佳状态,只要需要,系统就会使用它们,不用担心。

如果系统的free memory和inactive memory都很少,而active memory很多,说明你的[内存]不够了。当然一开机,大部分[内存]都是free,这时系统反而不在最佳状态,因为很多数据都需要从硬盘调用,速度反而慢了。

SSDiskInfo

磁盘信息

// Get the total disk space in long format
+ (long long)longDiskSpace {
    // Get the long long disk space    
    @try {
        // Set up variables
        long long diskSpace = 0L;
        NSError *error = nil;
        NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:&error];
        
        // Get the file attributes of the home directory assuming no errors
        if (error == nil) {
            // Get the size of the filesystem
            diskSpace = [[fileAttributes objectForKey:NSFileSystemSize] longLongValue];
        } else {
            // Error, return nil
            return -1;
        }
        
        // Check to make sure it's a valid size
        if (diskSpace <= 0) {
            // Invalid size
            return -1;
        }
        
        // Successful
        return diskSpace;
    }
    @catch (NSException *exception) {
        // Error
        return -1;
    }
}

磁盘大小

// Get the total free disk space in long format
+ (long long)longFreeDiskSpace {
    // Get the long total free disk space   
    @try {
        // Set up the variables
        long long FreeDiskSpace = 0L;
        NSError *error = nil;
        NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:&error];
        
        // Get the file attributes of the home directory assuming no errors
        if (error == nil) {
            FreeDiskSpace = [[fileAttributes objectForKey:NSFileSystemFreeSize] longLongValue];
        } else {
            // There was an error
            return -1;
        }
        
        // Check for valid size
        if (FreeDiskSpace <= 0) {
            // Invalid size
            return -1;
        }
        
        // Successful
        return FreeDiskSpace;
    }
    @catch (NSException *exception) {
        // Error
        return -1;
    }
}

获取磁盘剩余空间大小

SSAccelerometerInfo

加速度计

// Device Orientation
+ (UIInterfaceOrientation)deviceOrientation {
    // Get the device's current orientation
    @try {
        #if !(defined(__has_feature) && __has_feature(attribute_availability_app_extension))
            // Device orientation
            UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
        
            // Successful
            return orientation;
        #endif
    }
    @catch (NSException *exception) {
        return -1;
    }
    // Error
    return -1;
}

获取设备方向,根据状态栏判断

// Start logging motion data
- (void)startLoggingMotionData {
    motionManager = [[CMMotionManager alloc] init];
    motionManager.deviceMotionUpdateInterval = 0.01; //100 Hz
    motionManager.accelerometerUpdateInterval = 0.01;
    motionManager.gyroUpdateInterval = 0.01;
    
    // Limiting the concurrent ops to 1 is a cheap way to avoid two handlers editing the same
    // string at the same time.
    deviceMotionQueue = [[NSOperationQueue alloc] init];
    [deviceMotionQueue setMaxConcurrentOperationCount:1];
    
    accelQueue = [[NSOperationQueue alloc] init];
    [accelQueue setMaxConcurrentOperationCount:1];
    
    gyroQueue = [[NSOperationQueue alloc] init];
    [gyroQueue setMaxConcurrentOperationCount:1];

    // Logging Motion Data
    
    CMDeviceMotionHandler motionHandler = ^(CMDeviceMotion *motion, NSError *error) {
        [self processMotion:motion withError:error];
    };
    
    CMGyroHandler gyroHandler = ^(CMGyroData *gyroData, NSError *error) {
        [self processGyro:gyroData withError:error];
    };
    
    CMAccelerometerHandler accelHandler = ^(CMAccelerometerData *accelerometerData, NSError *error) {
        [self processAccel:accelerometerData withError:error];
    };
    
    [motionManager startDeviceMotionUpdatesToQueue:deviceMotionQueue withHandler:motionHandler];
    
    [motionManager startGyroUpdatesToQueue:gyroQueue withHandler:gyroHandler];
    
    [motionManager startAccelerometerUpdatesToQueue:accelQueue withHandler:accelHandler];
}

// Stop logging motion data
- (void)stopLoggingMotionData {
    
    // Stop everything
    [motionManager stopDeviceMotionUpdates];
    [deviceMotionQueue waitUntilAllOperationsAreFinished];
    
    [motionManager stopAccelerometerUpdates];
    [accelQueue waitUntilAllOperationsAreFinished];
    
    [motionManager stopGyroUpdates];
    [gyroQueue waitUntilAllOperationsAreFinished];
    
}

#pragma mark - Set Motion Variables when Updating (in background)

- (void)processAccel:(CMAccelerometerData*)accelData withError:(NSError*)error {
    rawAccelerometerString = [NSString stringWithFormat:@"%f,%f,%f,%f\n", accelData.timestamp,
                              accelData.acceleration.x,
                              accelData.acceleration.y,
                              accelData.acceleration.z,
                              nil];
}

- (void)processGyro:(CMGyroData*)gyroData withError:(NSError*)error {
    
    rawGyroscopeString = [NSString stringWithFormat:@"%f,%f,%f,%f\n", gyroData.timestamp,
                          gyroData.rotationRate.x,
                          gyroData.rotationRate.y,
                          gyroData.rotationRate.z,
                          nil];
}

- (void)processMotion:(CMDeviceMotion*)motion withError:(NSError*)error {
    
    attitudeString = [NSString stringWithFormat:@"%f,%f,%f,%f\n", motion.timestamp,
                      motion.attitude.roll,
                      motion.attitude.pitch,
                      motion.attitude.yaw,
                      nil];
    
    gravityString = [NSString stringWithFormat:@"%f,%f,%f,%f\n", motion.timestamp,
                     motion.gravity.x,
                     motion.gravity.y,
                     motion.gravity.z,
                     nil];
    
    magneticFieldString = [NSString stringWithFormat:@"%f,%f,%f,%f,%d\n", motion.timestamp,
                           motion.magneticField.field.x,
                           motion.magneticField.field.y,
                           motion.magneticField.field.z,
                           (int)motion.magneticField.accuracy,
                           nil];
    
    rotationRateString = [NSString stringWithFormat:@"%f,%f,%f,%f\n", motion.timestamp,
                          motion.rotationRate.x,
                          motion.rotationRate.y,
                          motion.rotationRate.z,
                          nil];
    
    userAccelerationString = [NSString stringWithFormat:@"%f,%f,%f,%f\n", motion.timestamp,
                              motion.userAcceleration.x,
                              motion.userAcceleration.y,
                              motion.userAcceleration.z,
                              nil];
    
}

陀螺仪 加速度计等的基本用法。不做过多介绍

SSLocalizationInfo

本地信息

// Country
+ (NSString *)country {
    // Get the user's country
    @try {
        // Get the locale
        NSLocale *locale = [NSLocale currentLocale];
        // Get the country from the locale
        NSString *country = [locale localeIdentifier];
        // Check for validity
        if (country == nil || country.length <= 0) {
            // Error, invalid country
            return nil;
        }
        // Completed Successfully
        return country;
    }
    @catch (NSException *exception) {
        // Error
        return nil;
    }
}

国家代号

// Language
+ (NSString *)language {
    // Get the user's language
    @try {
        // Get the list of languages
        NSArray *languageArray = [NSLocale preferredLanguages];
        // Get the user's language
        NSString *language = [languageArray objectAtIndex:0];
        // Check for validity
        if (language == nil || language.length <= 0) {
            // Error, invalid language
            return nil;
        }
        // Completed Successfully
        return language;
    }
    @catch (NSException *exception) {
        // Error
        return nil;
    }
}

当地语言代号

// TimeZone
+ (NSString *)timeZone {
    // Get the user's timezone
    @try {
        // Get the system timezone
        NSTimeZone *localTime = [NSTimeZone systemTimeZone];
        // Convert the time zone to a string
        NSString *timeZone = [localTime name];
        // Check for validity
        if (timeZone == nil || timeZone.length <= 0) {
            // Error, invalid TimeZone
            return nil;
        }
        // Completed Successfully
        return timeZone;
    }
    @catch (NSException *exception) {
        // Error
        return nil;
    }
}

所在时区

// Currency Symbol
+ (NSString *)currency {
    // Get the user's currency
    @try {
        // Get the system currency
        NSString *currency = [[NSLocale currentLocale] objectForKey:NSLocaleCurrencySymbol];
        // Check for validity
        if (currency == nil || currency.length <= 0) {
            // Error, invalid Currency
            return nil;
        }
        // Completed Successfully
        return currency;
    }
    @catch (NSException *exception) {
        // Error
        return nil;
    }
}

当地的货币符号

SSApplicationInfo


// Application Version
+ (NSString *)applicationVersion {
    // Get the Application Version Number
    @try {
        
        // Query the plist for the version
        NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
        
        // Validate the Version
        if (version == nil || version.length <= 0) {
            // Invalid Version number
            return nil;
        }
        // Successful
        return version;
    }
    @catch (NSException *exception) {
        // Error
        return nil;
    }
}

获取app版本

// Clipboard Content
+ (NSString *)clipboardContent {
    // Get the string content of the clipboard (copy, paste)
    @try {
        // Get the Pasteboard
        UIPasteboard *pasteBoard = [UIPasteboard generalPasteboard];
        // Get the string value of the pasteboard
        NSString *clipboardContent = [pasteBoard string];
        // Check for validity
        if (clipboardContent == nil || clipboardContent.length <= 0) {
            // Error, invalid pasteboard
            return nil;
        }
        // Successful
        return clipboardContent;
    }
    @catch (NSException *exception) {
        // Error
        return nil;
    }
}

获取剪切板内容

// Application CPU Usage
+ (float)cpuUsage {
    @try {
        kern_return_t kr;
        task_info_data_t tinfo;
        mach_msg_type_number_t task_info_count;
        
        task_info_count = TASK_INFO_MAX;
        kr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)tinfo, &task_info_count);
        if (kr != KERN_SUCCESS) {
            return -1;
        }
        
        task_basic_info_t      basic_info;
        thread_array_t         thread_list;
        mach_msg_type_number_t thread_count;
        
        thread_info_data_t     thinfo;
        mach_msg_type_number_t thread_info_count;
        
        thread_basic_info_t basic_info_th;
        uint32_t stat_thread = 0; // Mach threads
        
        basic_info = (task_basic_info_t)tinfo;
        
        // get threads in the task
        kr = task_threads(mach_task_self(), &thread_list, &thread_count);
        if (kr != KERN_SUCCESS) {
            return -1;
        }
        if (thread_count > 0)
            stat_thread += thread_count;
        
        long tot_sec = 0;
        long tot_usec = 0;
        float tot_cpu = 0;
        int j;
        
        for (j = 0; j < thread_count; j++)
        {
            thread_info_count = THREAD_INFO_MAX;
            kr = thread_info(thread_list[j], THREAD_BASIC_INFO,
                             (thread_info_t)thinfo, &thread_info_count);
            if (kr != KERN_SUCCESS) {
                return -1;
            }
            
            basic_info_th = (thread_basic_info_t)thinfo;
            
            if (!(basic_info_th->flags & TH_FLAGS_IDLE)) {
                tot_sec = tot_sec + basic_info_th->user_time.seconds + basic_info_th->system_time.seconds;
                tot_usec = tot_usec + basic_info_th->system_time.microseconds + basic_info_th->system_time.microseconds;
                tot_cpu = tot_cpu + basic_info_th->cpu_usage / (float)TH_USAGE_SCALE * 100.0;
            }
            
        } // for each thread
        
        kr = vm_deallocate(mach_task_self(), (vm_offset_t)thread_list, thread_count * sizeof(thread_t));
        assert(kr == KERN_SUCCESS);
        
        return tot_cpu;
    }
    @catch (NSException *exception) {
        // Error
        return -1;
    }
}

当前应用cpu使用情况

SSUUID

// CFUUID
+ (NSString *)cfuuid {
    // Create a new CFUUID (Unique, random ID number) (Always different)
    @try {
        // Create a new instance of CFUUID using CFUUIDCreate using the default allocator
        CFUUIDRef theUUID = CFUUIDCreate(kCFAllocatorDefault);
        
        // Check to make sure it exists
        if (theUUID)
        {
            // Make the new UUID String
            NSString *tempUniqueID = (__bridge NSString *)CFUUIDCreateString(kCFAllocatorDefault, theUUID);
            
            // Check to make sure it created it
            if (tempUniqueID == nil || tempUniqueID.length <= 0) {
                // Error, Unable to create
                // Release the UUID Reference
                CFRelease(theUUID);
                // Return nil
                return nil;
            }
            
            // Release the UUID Reference
            CFRelease(theUUID);
            
            // Successful
            return tempUniqueID;
        } else {
            // Error
            // Release the UUID Reference
            CFRelease(theUUID);
            // Return nil
            return nil;
        }
    }
    @catch (NSException *exception) {
        // Error
        return nil;
    }
}

获取一个随机的uuid

你可能感兴趣的:(SystemServices 库源码分析(获取设备信息)(3))