2018-01-29 iOS获取网络状态

最近发现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

例如在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
 - (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(@"没网");
         }
     }];
 }

摘自 iOS 判断当前网络状态的三种方法

你可能感兴趣的:(2018-01-29 iOS获取网络状态)