最近发现iOS项目里面获取网络状态有点问题,查了数据库没有一个4G的,第一想法就是当初没有4G这个选项,查了一下,果然没有,于是搜索了一堆,找到了一些的方法,过来总结一下。
1、Reachability
这是来自官方的方法,可以点击此处进入网页下载(标题左上方有个Download Sample Code按钮)
下载后将其中的Reachability.h与.m文件放入自己的项目中,add就可以用啦!
在.h中enum有三个枚举值:
typedef enum : NSInteger { NotReachable = 0, ReachableViaWiFi, ReachableViaWWAN } NetworkStatus;
这分别代表的是无网络,wifi网络,蜂窝网络(2g,3g,4g)。
实现
在调用的地方添加头文件
#import<Reachability.h>
例如在getInternetStatus函数中实现,则键入以下代码:
-(NString)getInternetStatus{ Reachability *reachability = [Reachability reachabilityWithHostName:@"www.apple.com"]; NetworkStatus internetStatus = [reachability currentReachabilityStatus]; NSString *net = @"WIFI"; switch(internetStatus){ case ReachableViaWiFi: net = @"WIFI"; break; case ReachableViaWWAN: net = @"数据流量"; //net = [self getNetType];//可具体判断 break; case NotReachable: net = @"无网络连接"; break; } }
不过这里还有个问题,就是当www.apple.com访问较慢,或者无法访问时,就会被卡顿在这个地方,所以这里还可以再调整一下。
Reachability *reachability = [Reachability reachabilityWithHostName:@"www.apple.com"]; NetworkStatus internetStatus = [reachability currentReachabilityStatus];
可以修改为
待定
我们有时还要判断数据流量具体是2g,3g还是4g,所以这时就要使用到CTTelephonyNetworkInfo类了。
首先在项目中添加CTTelephonyNetworkInfo.framework,并且导入头文件,调用以下方法即可:
#import<CTTelephonyNetworkInfo.h> - (NSString *)getNetType{ CTTelephonyNetworkInfo *info = [[CTTelephonyNetworkInfo alloc] init]; NSString *currentStatus = info.currentRadioAccessTechnology; if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyGPRS"]) { netconnType = @"GPRS"; }else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyEdge"]) { netconnType = @"2.75G EDGE"; }else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyWCDMA"]){ netconnType = @"3G"; }else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyHSDPA"]){ netconnType = @"3.5G HSDPA"; }else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyHSUPA"]){ netconnType = @"3.5G HSUPA"; }else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyCDMA1x"]){ netconnType = @"2G"; }else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyCDMAEVDORev0"]){ netconnType = @"3G"; }else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyCDMAEVDORevA"]){ netconnType = @"3G"; }else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyCDMAEVDORevB"]){ netconnType = @"3G"; }else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyeHRPD"]){ netconnType = @"HRPD"; }else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyLTE"]){ netconnType = @"4G"; } }
2、通过系统的statusBar判断
这个方法是获取状态栏上的联网方式,不过在隐藏状态栏以及iPhone X上无法获取,iX上甚至会可能崩溃,这里可能是因为苹果修改了statusBar的keyPath,所以获取了一个nil,导致崩溃。
实现
直接调用以下方法获取
+ (NSString *)networkingStatusFromStatusbar{ UIApplication *app = [UIApplication sharedApplication];//获取当前app NSArray *chidren = [[[app valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews]; int type = 0; for(id child in children){ if([child isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]]) { type = [[child valueForKeyPath:@"dataNetworkType"] intValue]; } } NSString *stateString = @"wifi"; switch(type) { case 0: stateString = @"notReachable"; break; case 1: stateString = @"2g"; break; case 2: stateString = @"3g"; break; case 3: stateString = @"4g"; break; case 4: stateString = @"LTE"; break; case 5: stateString = @"wifi"; break; default: break; } return stateString; }
3、通过AFNetworking
这个方法能够写在AppDelegate中,实时监测网络变化,做相应处理。
实现
#pragma mark - ------------- 监测网络状态 ------------- - (void)monitorNetworking { [[AFNetworkReachabilityManager sharedManager] startMonitoring]; [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { switch (status) { case -1: NSLog(@"未知网络"); break; case 0: NSLog(@"网络不可达"); break; case 1: { NSLog(@"GPRS网络"); //发通知,带头搞事 [[NSNotificationCenter defaultCenter] postNotificationName:@"monitorNetworking" object:@"1" userInfo:nil]; } break; case 2: { NSLog(@"wifi网络"); //发通知,搞事情 [[NSNotificationCenter defaultCenter] postNotificationName:@"monitorNetworking" object:@"2" userInfo:nil]; } break; default: break; } if (status == AFNetworkReachabilityStatusReachableViaWWAN || status == AFNetworkReachabilityStatusReachableViaWiFi) { NSLog(@"有网"); }else{ NSLog(@"没网"); } }]; }