KVC
项目中开始是使用KVC获取StatusBar
的属性,从而得到当前网络类型方法如下
- (NSString *)getNetStatus {
NSArray *children = [[[[UIApplication sharedApplication] valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];
NSString *state = nil;
int netType = 0;
for (id child in children) {
if ([child isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")]) {
netType = [[child valueForKeyPath:@"dataNetworkType"] intValue];
switch (netType) {
case 0:
state = @"无网络";
break;
case 1:
state = @"2G";
break;
case 2:
state = @"3G";
break;
case 3:
state = @"4G";
break;
case 5:
state = @"WIFI";
break;
default:
state = @"未知网络";
break;
}
}
}
return state;
}
但是在iPhone X设备上以上方法失效并引发崩溃,所以我们尝试重新遍历StatusBar
的属性
//obj 即为被遍历对象
unsigned int outCount = 0;
Ivar *ivars = class_copyIvarList([obj class], &outCount);
for (int i = 0; i < outCount; i++) {
Ivar ivar = ivars[i];
printf("======== |%s\n", ivar_getName(ivar));
}
之后获取到以下Path,发现类似dataNetworkType
的_networkTypeView
NSArray *items = [[[[UIApplication sharedApplication] valueForKeyPath:@"statusBar"] valueForKeyPath:@"statusBar"] items];
id obj = [[items valueForKeyPath:@"_UIStatusBarCellularExpandedItem"] valueForKeyPath:@"_networkTypeView"];
但纵览整个属性列表,没有发现可用的NetworkType
,只能弃用
Reachability
通过翻阅文档发现可以通过CTTelephonyNetworkInfo
获取网络运营商相关信息,这不就是3G,4G技术名称嘛!!!
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyGPRS __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyEdge __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyWCDMA __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyHSDPA __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyHSUPA __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyCDMA1x __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyCDMAEVDORev0 __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyCDMAEVDORevA __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyCDMAEVDORevB __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyeHRPD __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyLTE __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
之后再次发现Reachability
中已对此做了相应封装,拿来即用,美滋滋。戳这儿下载
typedef enum : NSInteger {
NotReachable = 0,
ReachableViaWiFi,
kReachableVia2G,
kReachableVia3G,
kReachableVia4G
} NetworkStatus;
PS:最新版Reachability
已简化枚举
typedef enum : NSInteger {
NotReachable = 0,
ReachableViaWiFi,
ReachableViaWWAN
} NetworkStatus;
经过改写后的方法如下
+ (int)getNetStatus {
NSString *stateString = nil;
int netStatusNumber = 0;
switch ([[Reachability reachabilityForInternetConnection] currentReachabilityStatus]) {
case NotReachable: {
stateString = @"无网络";
netStatusNumber = 0;
}
break;
case kReachableVia2G: {
stateString = @"2G";
netStatusNumber = 2;
}
break;
case kReachableVia3G: {
stateString = @"3G";
netStatusNumber = 3;
}
break;
case kReachableVia4G: {
stateString = @"4G";
netStatusNumber = 4;
}
break;
case ReachableViaWiFi: {
stateString = @"WIFI";
netStatusNumber = 1;
}
break;
default: {
stateString = @"不可识别的网络";
netStatusNumber = -1;
}
break;
}
return netStatusNumber;
}
网友评论