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,第四个元素
是一个地址族,第五个和第六个指定做什么,如下表所示:
路由域支持三种操作,由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