iOS开发之网络检测

转自:http://blog.csdn.net/drift_axe/article/details/51463835点击打开链接

概述


iOS开发中,经常要根据实时的网络状况,对UI及逻辑做出调整,以提高用户的使用体验。


方案


方案一:使用苹果封装的Reachability进行网络检测


如何下载Reachability?

打开Xcode,用快捷键(shift + command + 0)打开并搜索Reachability,如下图,下载即可。






示例代码:

  1. #import "Reachability.h"  
  2.   
  3. @interface LeftViewController ()  
  4. @property (strongnonatomicReachability *reachability;  
  5. @end  
  6.   
  7. @implementation LeftViewController  
  8.   
  9. - (void)viewDidLoad {  
  10.     [super viewDidLoad];  
  11.   
  12.     // 此处一定要声明全局变量,否则通知是不会执行的   
  13.   
  14.     self.reachability = [Reachability reachabilityForInternetConnection];  
  15.   
  16.     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityStatusChange:) name:kReachabilityChangedNotification object:_reachability];  
  17.     [_reachability startNotifier];  
  18.       
  19. }  
  20.   
  21. - (void)reachabilityStatusChange:(NSNotification *)notification {  
  22.     Reachability *reachability = (Reachability *)[notification object];  
  23.     NSParameterAssert([reachability isKindOfClass:[Reachability class]]);  
  24.     NetworkStatus status = [reachability currentReachabilityStatus];  
  25.     NSLog(@"%ld",(long)status);  
  26. }  


问题1:由于上述的监测方式是利用KVO机制,所以是在网络状态变化后才会收到通知,并不是严格意义上的实时检测网络。我们大部分是需要在点击某个按钮,进行网络请求的时候,会检测网络状况,如果没有网络,那就没必要去做请求操作。这时你可以用弹窗的形式提示用户检查网络设置。况且每个视图控制器里都要去注册通知,在控制器销毁的时候移除通知,是个很繁琐的过程,也不利于代码维护(当然你在父视图控制器里用此方法,其他控制器都继承之)。

问题2:由于默认只提供了三种网络状态:NotReachable、reachableViaWiFi和reachableViaWWAN,如果我们要区分2G/3G/4G网络,则需要对Reachability进行相应的更改。

  1. typedef enum : NSInteger {  
  2.       
  3.     NotReachable = 0,  
  4.     ReachableViaWiFi,  
  5.     ReachableViaWWAN,  
  6.   
  7.         ReachableVia2G,  
  8.         ReachableVia3G,  
  9.         ReachableVia4G  
  10.       
  11. } NetworkStatus;  

 

在源码的基础上,添加2G/3G/4G枚举状态,接下来在.m中修改方法:- networkStatusForFlags:

  1. - (NetworkStatus)networkStatusForFlags:(SCNetworkReachabilityFlags)flags {  
  2.       
  3.     PrintReachabilityFlags(flags, "networkStatusForFlags");  
  4.       
  5.     if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)  
  6.     {  
  7.         // The target host is not reachable.  
  8.         return NotReachable;  
  9.     }  
  10.   
  11.     NetworkStatus returnValue = NotReachable;  
  12.   
  13.     if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)  
  14.     {  
  15.         /* 
  16.          If the target host is reachable and no connection is required then we'll assume (for now) that you're on Wi-Fi... 
  17.          */  
  18.         returnValue = ReachableViaWiFi;  
  19.     }  
  20.   
  21.     if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||  
  22.         (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))  
  23.     {  
  24.         /* 
  25.          ... and the connection is on-demand (or on-traffic) if the calling application is using the CFSocketStream or higher APIs... 
  26.          */  
  27.   
  28.         if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)  
  29.         {  
  30.             /* 
  31.              ... and no [user] intervention is needed... 
  32.              */  
  33.             returnValue = ReachableViaWiFi;  
  34.         }  
  35.     }  
  36.       
  37.     if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)  
  38.     {  
  39.         /* 
  40.          ... but WWAN connections are OK if the calling application is using the CFNetwork APIs. 
  41.          */  
  42.           
  43.         if (NSFoundationVersionNumber >= NSFoundationVersionNumber_iOS_7_0) {  
  44.             CTTelephonyNetworkInfo  *info = [[CTTelephonyNetworkInfo alloc] init];  
  45.             NSString *currentRadioAccessTechnology = info.currentRadioAccessTechnology;  
  46.             if ([currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyLTE]) {  
  47.                 returnValue = ReachableVia4G;  
  48.             } else if ([currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyEdge] || [currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyGPRS]) {  
  49.                 returnValue = ReachableVia2G;  
  50.             } else {  
  51.                 returnValue = ReachableVia3G;  
  52.             }  
  53.               
  54.             return returnValue;  
  55.         }  
  56.           
  57.         if ((flags && kSCNetworkReachabilityFlagsTransientConnection) == kSCNetworkReachabilityFlagsTransientConnection) {  
  58.             if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == kSCNetworkReachabilityFlagsConnectionRequired) {  
  59.                 returnValue = ReachableVia2G;  
  60.                 return returnValue;  
  61.             }  
  62.             returnValue = ReachableVia3G;  
  63.             return returnValue;  
  64.         }  
  65.           
  66.         returnValue = ReachableViaWWAN;  
  67.     }  
  68.       
  69.     return returnValue;  
  70. }  

方案二:使用AFNetworkReachabilityManager进行网络监测


此类处于AFNetworking第三方库中,可自行下载。


  1. #import "AppDelegate.h"  
  2.   
  3. @interface AppDelegate ()  
  4.   
  5. @end  
  6.   
  7. @implementation AppDelegate  
  8.   
  9.   
  10. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
  11.     // Override point for customization after application launch.  
  12.   
  13.     // 在此全程检测网络状态,全局可以获取当前的网络状态  
  14.   
  15.     AFNetworkReachabilityManager *networkReachabilityManager = [AFNetworkReachabilityManager sharedManager];  
  16.   
  17.     [networkReachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {  
  18.         // insert your code ...  
  19.     }];  
  20.     [networkReachabilityManager startMonitoring];      
  21. }  

在需要的地方,调用下面的方法,便可知道目前的网络状态。

  1. - (AFNetworkReachabilityStatus)networkReachabilityStatus {  
  2.     return [AFNetworkReachabilityManager sharedManager].networkReachabilityStatus;  
  3. }  


方案三:使用RealReachability进行实时网络检测


如果我们连接上一个公用WiFi后,用上面两种方式监测网络,其结果都认为你的APP已经连接上了网络,但实际上只是本地连接上,并没有真正接入网络,大家应该有体会。RealReachability提供了实时网络监测的功能,详情可参考链接:点击打开链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值