iOS 关于网络类型的判断
说明 在iOS 中随着iPhone X 手机的上市,并且iOS 10系统发布后,现在越来越多的app 开始注重网络状态的情况了,一个好的准确的网络状态会给用户带来一个完全不同的体验效果。
typedef NS_ENUM(NSInteger, NetworkType) {
NetworkTypeUnknown = 0,
NetworkTypeAirplane,
NetworkTypeOffline,
NetworkTypeline,
NetworkTypeCellularData,
NetworkTypeCellularData2G,
NetworkTypeCellularData3G,
NetworkTypeCellularData4G,
NetworkTypeCellularDataLTE,
NetworkTypeWiFi
};
typedef struct{
NetworkType stateType;
__unsafe_unretained NSString * stateStr;
}netStateStruct;
}
-(netStateStruct) dataNetworkTypeFromStatusBar {
UIApplication *app = [UIApplication sharedApplication];
id statusBar = [app valueForKeyPath:@"statusBar"];
netStateStruct netStruct;
NetworkType netType;
NSString *network = @"Unknown";
netStruct.stateStr = network;
netType = NetworkTypeUnknown;
netStruct.stateType = netType;
if (statusBar == nil ){
return netStruct;
}
@try {
if ([statusBar isKindOfClass:NSClassFromString(@"UIStatusBar_Modern")]) { // 在 iPhone X 上 statusBar 属于 UIStatusBar_Modern
id statusBarView = [statusBar valueForKeyPath:@"statusBar"];
UIView *foregroundView = [statusBarView valueForKeyPath:@"foregroundView"];
NSArray *subviews = [[foregroundView subviews][2] subviews];
for (id subview in subviews) {
if ([subview isKindOfClass:NSClassFromString(@"_UIStatusBarWifiSignalView")]) {
network = @"wifi";
netType = NetworkTypeWiFi;
break;
}else if ([subview isKindOfClass:NSClassFromString(@"_UIStatusBarStringView")]) {
network = [subview valueForKeyPath:@"originalText"];
NSArray *aName = [NSArray arrayWithObjects:@"2g",@"3g",@"4g",@"lte",@"wifi",nil];
int index = (int)[aName indexOfObject:[network lowercaseString]];
switch(index)
{
case 0:
netType = NetworkTypeCellularData2G;
break;
case 1:
netType = NetworkTypeCellularData3G;
break;
case 2:
netType = NetworkTypeCellularData4G;
break;
case 3:
netType = NetworkTypeCellularDataLTE;
break;
case 4:
netType = NetworkTypeWiFi;
break;
default:
netType = NetworkTypeUnknown;
break;
}
break;
}
}
}else {
//非 iPhone X
UIView *foregroundView = [statusBar valueForKeyPath:@"foregroundView"];
NSArray *subviews = [foregroundView subviews];
for (id subview in subviews) {
NSLog(@"subView is class %@",[NSString stringWithFormat:@"%@",[subview class]]);
if ([subview isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")]) {
int networkType = [[subview valueForKeyPath:@"dataNetworkType"] intValue];
// type == 1 => 2G
// type == 2 => 3G
// type == 3 => 4G
// type == 4 => LTE
// type == 5 => Wi-Fi
switch (networkType) {
case 0:
network = @"Unknown";
netType = NetworkTypeUnknown;
break;
case 1:
network = @"2G";
netType = NetworkTypeCellularData2G;
break;
case 2:
network = @"3G";
netType = NetworkTypeCellularData3G;
break;
case 3:
network = @"4G";
netType = NetworkTypeCellularData4G;
break;
case 4:
network = @"LTE";
netType = NetworkTypeCellularDataLTE;
break;
case 5:
network = @"wifi";
netType = NetworkTypeWiFi;
break;
default:
break;
}
}else if ([subview isKindOfClass:NSClassFromString(@"UIStatusBarAirplaneModeItemView")])
{
network = @"Airplane";
netType = NetworkTypeAirplane;
break;
}
}
}
} @catch (NSException *exception) {
NSLog(@"网络错误");
} @finally {
netStruct.stateStr = network;
netStruct.stateType = netType;
return netStruct;
}
}
网友评论