iOS实现实时检测网络状态的示例代码
前言
在网络应用中,需要对用户设备的网络状态进行实时监控,有两个目的:
(1)让用户了解自己的网络状态,防止一些误会(比如怪应用无能)
(2)根据用户的网络状态进行智能处理,节省用户流量,提高用户体验
WIFI\3G网络:自动下载高清图片
低速网络:只下载缩略图
没有网络:只显示离线的缓存数据
最近在工作中遇到一个功能就是根据用户当前的网络状,用户未联网需要提示一下,如果是Wifi可以推荐一些图片新闻,如果是3G模式设置为无图的模式,获取网络状态比较简单,毕竟中国现在的流量还是一个比较贵的状态,哪天用户发现App消耗流量过多说不定就干掉了App。不过苹果的Reachability都解决了以上问题,使用起来也比较方便,所以就总结以下,具体的稍微简单分析下,下面话不多说,来一起看看详细的介绍:
示例代码
Reachability.h头文件代码:
#import#import #import //http://www.cnblogs.com/xiaofeixiang typedefenum:NSInteger{ NotReachable=0, ReachableViaWiFi, ReachableViaWWAN }NetworkStatus; externNSString*kReachabilityChangedNotification; @interfaceReachability:NSObject /*! *Usetocheckthereachabilityofagivenhostname. */ +(instancetype)reachabilityWithHostName:(NSString*)hostName; /*! *UsetocheckthereachabilityofagivenIPaddress. */ +(instancetype)reachabilityWithAddress:(conststructsockaddr_in*)hostAddress; /*! *Checkswhetherthedefaultrouteisavailable.Shouldbeusedbyapplicationsthatdonotconnecttoaparticularhost. */ +(instancetype)reachabilityForInternetConnection; /*! *CheckswhetheralocalWiFiconnectionisavailable. */ +(instancetype)reachabilityForLocalWiFi; /*! *Startlisteningforreachabilitynotificationsonthecurrentrunloop. */ -(BOOL)startNotifier; -(void)stopNotifier; -(NetworkStatus)currentReachabilityStatus; /*! *WWANmaybeavailable,butnotactiveuntilaconnectionhasbeenestablished.WiFimayrequireaconnectionforVPNonDemand. */ -(BOOL)connectionRequired; @end
Reachability.m文件:
#import#import #import #import #import #import"Reachability.h" NSString*kReachabilityChangedNotification=@"kNetworkReachabilityChangedNotification"; #pragmamark-Supportingfunctions #definekShouldPrintReachabilityFlags1 staticvoidPrintReachabilityFlags(SCNetworkReachabilityFlagsflags,constchar*comment) { #ifkShouldPrintReachabilityFlags NSLog(@"ReachabilityFlagStatus:%c%c%c%c%c%c%c%c%c%s\n", //当前网络2G/3G/4G蜂窝网络 (flags&kSCNetworkReachabilityFlagsIsWWAN)?'W':'-', //网络是否可达 (flags&kSCNetworkReachabilityFlagsReachable)?'R':'-', (flags&kSCNetworkReachabilityFlagsTransientConnection)?'t':'-', (flags&kSCNetworkReachabilityFlagsConnectionRequired)?'c':'-', (flags&kSCNetworkReachabilityFlagsConnectionOnTraffic)?'C':'-', (flags&kSCNetworkReachabilityFlagsInterventionRequired)?'i':'-', (flags&kSCNetworkReachabilityFlagsConnectionOnDemand)?'D':'-', (flags&kSCNetworkReachabilityFlagsIsLocalAddress)?'l':'-', (flags&kSCNetworkReachabilityFlagsIsDirect)?'d':'-', comment ); #endif } staticvoidReachabilityCallback(SCNetworkReachabilityReftarget,SCNetworkReachabilityFlagsflags,void*info) { #pragmaunused(target,flags) NSCAssert(info!=NULL,@"infowasNULLinReachabilityCallback"); NSCAssert([(__bridgeNSObject*)infoisKindOfClass:[Reachabilityclass]],@"infowaswrongclassinReachabilityCallback"); //http://www.cnblogs.com/xiaofeixiang Reachability*noteObject=(__bridgeReachability*)info; //Postanotificationtonotifytheclientthatthenetworkreachabilitychanged. [[NSNotificationCenterdefaultCenter]postNotificationName:kReachabilityChangedNotificationobject:noteObject]; } #pragmamark-Reachabilityimplementation @implementationReachability { BOOL_alwaysReturnLocalWiFiStatus;//defaultisNO SCNetworkReachabilityRef_reachabilityRef; } //通过域名进行实例化博客园-Fly_Elephant +(instancetype)reachabilityWithHostName:(NSString*)hostName { Reachability*returnValue=NULL; SCNetworkReachabilityRefreachability=SCNetworkReachabilityCreateWithName(NULL,[hostNameUTF8String]); if(reachability!=NULL) { returnValue=[[selfalloc]init]; if(returnValue!=NULL) { returnValue->_reachabilityRef=reachability; returnValue->_alwaysReturnLocalWiFiStatus=NO; } } returnreturnValue; } //通过ip地址实例化Reachability +(instancetype)reachabilityWithAddress:(conststructsockaddr_in*)hostAddress { SCNetworkReachabilityRefreachability=SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault,(conststructsockaddr*)hostAddress); Reachability*returnValue=NULL; if(reachability!=NULL) { returnValue=[[selfalloc]init]; if(returnValue!=NULL) { returnValue->_reachabilityRef=reachability; returnValue->_alwaysReturnLocalWiFiStatus=NO; } } returnreturnValue; } //检测是否能够直接连上互联网 +(instancetype)reachabilityForInternetConnection { structsockaddr_inzeroAddress; bzero(&zeroAddress,sizeof(zeroAddress)); zeroAddress.sin_len=sizeof(zeroAddress); zeroAddress.sin_family=AF_INET; return[selfreachabilityWithAddress:&zeroAddress]; } //检测当前网络是否能够联上wifi +(instancetype)reachabilityForLocalWiFi { structsockaddr_inlocalWifiAddress; bzero(&localWifiAddress,sizeof(localWifiAddress)); localWifiAddress.sin_len=sizeof(localWifiAddress); localWifiAddress.sin_family=AF_INET; //IN_LINKLOCALNETNUMisdefinedin as169.254.0.0. localWifiAddress.sin_addr.s_addr=htonl(IN_LINKLOCALNETNUM); Reachability*returnValue=[selfreachabilityWithAddress:&localWifiAddress]; if(returnValue!=NULL) { returnValue->_alwaysReturnLocalWiFiStatus=YES; } returnreturnValue; } #pragmamark-Startandstopnotifier -(BOOL)startNotifier { BOOLreturnValue=NO; SCNetworkReachabilityContextcontext={0,(__bridgevoidvoid*)(self),NULL,NULL,NULL}; //SCNetworkReachabilitySetCallback函数为指定一个target //当设备对于这个target链接状态发生改变时(比如断开链接,或者重新连上),则回调reachabilityCallback函数, if(SCNetworkReachabilitySetCallback(_reachabilityRef,ReachabilityCallback,&context)) { if(SCNetworkReachabilityScheduleWithRunLoop(_reachabilityRef,CFRunLoopGetCurrent(),kCFRunLoopDefaultMode)) { returnValue=YES; } } returnreturnValue; } -(void)stopNotifier { if(_reachabilityRef!=NULL) { SCNetworkReachabilityUnscheduleFromRunLoop(_reachabilityRef,CFRunLoopGetCurrent(),kCFRunLoopDefaultMode); } } -(void)dealloc { [selfstopNotifier]; if(_reachabilityRef!=NULL) { CFRelease(_reachabilityRef); } } #pragmamark-NetworkFlagHandling -(NetworkStatus)localWiFiStatusForFlags:(SCNetworkReachabilityFlags)flags { PrintReachabilityFlags(flags,"localWiFiStatusForFlags"); NetworkStatusreturnValue=NotReachable; if((flags&kSCNetworkReachabilityFlagsReachable)&&(flags&kSCNetworkReachabilityFlagsIsDirect)) { returnValue=ReachableViaWiFi; } returnreturnValue; } -(NetworkStatus)networkStatusForFlags:(SCNetworkReachabilityFlags)flags { PrintReachabilityFlags(flags,"networkStatusForFlags"); if((flags&kSCNetworkReachabilityFlagsReachable)==0) { //Thetargethostisnotreachable. returnNotReachable; } NetworkStatusreturnValue=NotReachable; if((flags&kSCNetworkReachabilityFlagsConnectionRequired)==0) { /* Ifthetargethostisreachableandnoconnectionisrequiredthenwe'llassume(fornow)thatyou'reonWi-Fi... */ returnValue=ReachableViaWiFi; } if((((flags&kSCNetworkReachabilityFlagsConnectionOnDemand)!=0)|| (flags&kSCNetworkReachabilityFlagsConnectionOnTraffic)!=0)) { /* ...andtheconnectionison-demand(oron-traffic)ifthecallingapplicationisusingtheCFSocketStreamorhigherAPIs... */ if((flags&kSCNetworkReachabilityFlagsInterventionRequired)==0) { /* ...andno[user]interventionisneeded... */ returnValue=ReachableViaWiFi; } } if((flags&kSCNetworkReachabilityFlagsIsWWAN)==kSCNetworkReachabilityFlagsIsWWAN) { /* ...butWWANconnectionsareOKifthecallingapplicationisusingtheCFNetworkAPIs. */ returnValue=ReachableViaWWAN; } returnreturnValue; } -(BOOL)connectionRequired { NSAssert(_reachabilityRef!=NULL,@"connectionRequiredcalledwithNULLreachabilityRef"); SCNetworkReachabilityFlagsflags; if(SCNetworkReachabilityGetFlags(_reachabilityRef,&flags)) { return(flags&kSCNetworkReachabilityFlagsConnectionRequired); } returnNO; } //获取当前网络状态 -(NetworkStatus)currentReachabilityStatus { NSAssert(_reachabilityRef!=NULL,@"currentNetworkStatuscalledwithNULLSCNetworkReachabilityRef"); NetworkStatusreturnValue=NotReachable; SCNetworkReachabilityFlagsflags; if(SCNetworkReachabilityGetFlags(_reachabilityRef,&flags)) { if(_alwaysReturnLocalWiFiStatus) { returnValue=[selflocalWiFiStatusForFlags:flags]; } else { returnValue=[selfnetworkStatusForFlags:flags]; } } returnreturnValue; } @end
AppDelegate中的实现:
-(BOOL)application:(UIApplication*)applicationdidFinishLaunchingWithOptions:(NSDictionary*)launchOptions{ //添加一个系统通知 [[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(reachabilityChanged:)name:kReachabilityChangedNotificationobject:nil]; //初始化 self.internetReachability=[ReachabilityreachabilityForInternetConnection]; //通知添加到RunLoop [self.internetReachabilitystartNotifier]; [selfupdateInterfaceWithReachability:_internetReachability]; returnYES; }
回调函数:
(void)reachabilityChanged:(NSNotification*)note { Reachability*curReach=[noteobject]; NSParameterAssert([curReachisKindOfClass:[Reachabilityclass]]); [selfupdateInterfaceWithReachability:curReach]; } -(void)updateInterfaceWithReachability:(Reachability*)reachability { NetworkStatusnetStatus=[reachabilitycurrentReachabilityStatus]; switch(netStatus){ caseNotReachable: NSLog(@"====当前网络状态不可达=======http://www.cnblogs.com/xiaofeixiang"); break; caseReachableViaWiFi: NSLog(@"====当前网络状态为Wifi=======博客园-Fly_Elephant"); break; caseReachableViaWWAN: NSLog(@"====当前网络状态为3G=======keso"); break; } }
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。