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常值在<sys/sysctl.h>中定義),第二個元素可以:

 > AF_INET:  獲取或者設置影響網際協議的變量。下一級為使用某個IPPROTO_XXX常

值指定的具體協議。
> AF_LINK: 獲取或設置鏈路層信息,例如:PPP接口的數目。

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

AF_UNSPEC: 獲取或設置一些套接口層變量,例如套接口發送或接收緩沖區的最大大小

當name數組的第二個元素為AF_ROUTE時,第三個元素(協議號)總是為0,第四個元素
是一個地址族,第五個和第六個指定做什么,如下表所示:

image.png

路由域支持三種操作,由name[4]指定。(NET_RT_xxx常值在<sys/socket.h>中定義),這三種操作返回的信息通過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

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,869評論 18 139
  • 名詞延伸 通俗的說,域名就相當于一個家庭的門牌號碼,別人通過這個號碼可以很容易的找到你。如果把IP地址比作一間房子...
    楊大蝦閱讀 20,626評論 2 56
  • 文章圖片上傳不正常,如需文檔,可聯系微信:1017429387 目錄 1 安裝... 4 1.1 配置探針... ...
    Mrhappy_a7eb閱讀 6,430評論 0 5
  • 2018-3-3 1.感恩推拿師幫我推拿,讓我找到問題的根本。 2.感恩今天先生幫我買了漂亮的衣服和鞋子。感恩今天...
    道和與文淑閱讀 220評論 0 1
  • 在公司補作業,要被老板開除了
    呱呱我叫西瓜閱讀 194評論 2 2