全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

iOS实现实时检测网络状态的示例代码

前言

在网络应用中,需要对用户设备的网络状态进行实时监控,有两个目的:

(1)让用户了解自己的网络状态,防止一些误会(比如怪应用无能)

(2)根据用户的网络状态进行智能处理,节省用户流量,提高用户体验

  WIFI\3G网络:自动下载高清图片

  低速网络:只下载缩略图

  没有网络:只显示离线的缓存数据

最近在工作中遇到一个功能就是根据用户当前的网络状,用户未联网需要提示一下,如果是Wifi可以推荐一些图片新闻,如果是3G模式设置为无图的模式,获取网络状态比较简单,毕竟中国现在的流量还是一个比较贵的状态,哪天用户发现App消耗流量过多说不定就干掉了App 。 不过苹果的 Reachability 都解决了以上问题,使用起来也比较方便,所以就总结以下,具体的稍微简单分析下,下面话不多说,来一起看看详细的介绍:

示例代码

Reachability.h头文件代码:

#import <Foundation/Foundation.h> 
#import <SystemConfiguration/SystemConfiguration.h> 
#import <netinet/in.h> 
 
//http://www.cnblogs.com/xiaofeixiang 
typedef enum : NSInteger { 
 NotReachable = 0, 
 ReachableViaWiFi, 
 ReachableViaWWAN 
} NetworkStatus; 
 
 
extern NSString *kReachabilityChangedNotification; 
 
 
@interface Reachability : NSObject 
 
/*! 
 * Use to check the reachability of a given host name. 
 */ 
+ (instancetype)reachabilityWithHostName:(NSString *)hostName; 
 
/*! 
 * Use to check the reachability of a given IP address. 
 */ 
+ (instancetype)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress; 
 
/*! 
 * Checks whether the default route is available. Should be used by applications that do not connect to a particular host. 
 */ 
+ (instancetype)reachabilityForInternetConnection; 
 
/*! 
 * Checks whether a local WiFi connection is available. 
 */ 
+ (instancetype)reachabilityForLocalWiFi; 
 
/*! 
 * Start listening for reachability notifications on the current run loop. 
 */ 
- (BOOL)startNotifier; 
- (void)stopNotifier; 
 
- (NetworkStatus)currentReachabilityStatus; 
 
/*! 
 * WWAN may be available, but not active until a connection has been established. WiFi may require a connection for VPN on Demand. 
 */ 
- (BOOL)connectionRequired; 
 
@end

Reachability.m文件:

#import <arpa/inet.h> 
#import <ifaddrs.h> 
#import <netdb.h> 
#import <sys/socket.h> 
#import <CoreFoundation/CoreFoundation.h> 
#import "Reachability.h" 
NSString *kReachabilityChangedNotification = @"kNetworkReachabilityChangedNotification"; 
#pragma mark - Supporting functions 
#define kShouldPrintReachabilityFlags 1 
static void PrintReachabilityFlags(SCNetworkReachabilityFlags flags, const char* comment) 
{ 
#if kShouldPrintReachabilityFlags 
 NSLog(@"Reachability Flag Status: %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 
} 
static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info) 
{ 
#pragma unused (target, flags) 
 NSCAssert(info != NULL, @"info was NULL in ReachabilityCallback"); 
 NSCAssert([(__bridge NSObject*) info isKindOfClass: [Reachability class]], @"info was wrong class in ReachabilityCallback"); 
 //http://www.cnblogs.com/xiaofeixiang 
 Reachability* noteObject = (__bridge Reachability *)info; 
 // Post a notification to notify the client that the network reachability changed. 
 [[NSNotificationCenter defaultCenter] postNotificationName: kReachabilityChangedNotification object: noteObject]; 
} 
#pragma mark - Reachability implementation 
@implementation Reachability 
{ 
 BOOL _alwaysReturnLocalWiFiStatus; //default is NO 
 SCNetworkReachabilityRef _reachabilityRef; 
} 
//通过域名进行实例化 博客园-Fly_Elephant 
+ (instancetype)reachabilityWithHostName:(NSString *)hostName 
{ 
 Reachability* returnValue = NULL; 
 SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]); 
 if (reachability != NULL) 
 { 
 returnValue= [[self alloc] init]; 
 if (returnValue != NULL) 
 { 
  returnValue->_reachabilityRef = reachability; 
  returnValue->_alwaysReturnLocalWiFiStatus = NO; 
 } 
 } 
 return returnValue; 
} 
//通过ip地址实例化Reachability 
+ (instancetype)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress 
{ 
 SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)hostAddress); 
 Reachability* returnValue = NULL; 
 if (reachability != NULL) 
 { 
 returnValue = [[self alloc] init]; 
 if (returnValue != NULL) 
 { 
  returnValue->_reachabilityRef = reachability; 
  returnValue->_alwaysReturnLocalWiFiStatus = NO; 
 } 
 } 
 return returnValue; 
} 
//检测是否能够直接连上互联网 
+ (instancetype)reachabilityForInternetConnection 
{ 
 struct sockaddr_in zeroAddress; 
 bzero(&zeroAddress, sizeof(zeroAddress)); 
 zeroAddress.sin_len = sizeof(zeroAddress); 
 zeroAddress.sin_family = AF_INET; 
 return [self reachabilityWithAddress:&zeroAddress]; 
} 
//检测当前网络是否能够联上wifi 
+ (instancetype)reachabilityForLocalWiFi 
{ 
 struct sockaddr_in localWifiAddress; 
 bzero(&localWifiAddress, sizeof(localWifiAddress)); 
 localWifiAddress.sin_len = sizeof(localWifiAddress); 
 localWifiAddress.sin_family = AF_INET; 
 // IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0. 
 localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM); 
 Reachability* returnValue = [self reachabilityWithAddress: &localWifiAddress]; 
 if (returnValue != NULL) 
 { 
 returnValue->_alwaysReturnLocalWiFiStatus = YES; 
 } 
 return returnValue; 
} 
#pragma mark - Start and stop notifier 
- (BOOL)startNotifier 
{ 
 BOOL returnValue = NO; 
 SCNetworkReachabilityContext context = {0, (__bridge voidvoid *)(self), NULL, NULL, NULL}; 
 //SCNetworkReachabilitySetCallback函数为指定一个target 
 //当设备对于这个target链接状态发生改变时(比如断开链接,或者重新连上),则回调reachabilityCallback函数, 
 if (SCNetworkReachabilitySetCallback(_reachabilityRef, ReachabilityCallback, &context)) 
 { 
 if (SCNetworkReachabilityScheduleWithRunLoop(_reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode)) 
 { 
  returnValue = YES; 
 } 
 } 
 return returnValue; 
} 
- (void)stopNotifier 
{ 
 if (_reachabilityRef != NULL) 
 { 
 SCNetworkReachabilityUnscheduleFromRunLoop(_reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); 
 } 
} 
- (void)dealloc 
{ 
 [self stopNotifier]; 
 if (_reachabilityRef != NULL) 
 { 
 CFRelease(_reachabilityRef); 
 } 
} 
#pragma mark - Network Flag Handling 
- (NetworkStatus)localWiFiStatusForFlags:(SCNetworkReachabilityFlags)flags 
{ 
 PrintReachabilityFlags(flags, "localWiFiStatusForFlags"); 
 NetworkStatus returnValue = NotReachable; 
 if ((flags & kSCNetworkReachabilityFlagsReachable) && (flags & kSCNetworkReachabilityFlagsIsDirect)) 
 { 
 returnValue = ReachableViaWiFi; 
 } 
 return returnValue; 
} 
- (NetworkStatus)networkStatusForFlags:(SCNetworkReachabilityFlags)flags 
{ 
 PrintReachabilityFlags(flags, "networkStatusForFlags"); 
 if ((flags & kSCNetworkReachabilityFlagsReachable) == 0) 
 { 
 // The target host is not reachable. 
 return NotReachable; 
 } 
 NetworkStatus returnValue = NotReachable; 
 if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0) 
 { 
 /* 
  If the target host is reachable and no connection is required then we'll assume (for now) that you're on Wi-Fi... 
  */ 
 returnValue = ReachableViaWiFi; 
 } 
 if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) || 
 (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0)) 
 { 
 /* 
  ... and the connection is on-demand (or on-traffic) if the calling application is using the CFSocketStream or higher APIs... 
  */ 
 if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0) 
 { 
  /* 
  ... and no [user] intervention is needed... 
  */ 
  returnValue = ReachableViaWiFi; 
 } 
 } 
 if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN) 
 { 
 /* 
  ... but WWAN connections are OK if the calling application is using the CFNetwork APIs. 
  */ 
 returnValue = ReachableViaWWAN; 
 } 
 return returnValue; 
} 
- (BOOL)connectionRequired 
{ 
 NSAssert(_reachabilityRef != NULL, @"connectionRequired called with NULL reachabilityRef"); 
 SCNetworkReachabilityFlags flags; 
 if (SCNetworkReachabilityGetFlags(_reachabilityRef, &flags)) 
 { 
 return (flags & kSCNetworkReachabilityFlagsConnectionRequired); 
 } 
 return NO; 
} 
//获取当前网络状态 
- (NetworkStatus)currentReachabilityStatus 
{ 
 NSAssert(_reachabilityRef != NULL, @"currentNetworkStatus called with NULL SCNetworkReachabilityRef"); 
 NetworkStatus returnValue = NotReachable; 
 SCNetworkReachabilityFlags flags; 
 if (SCNetworkReachabilityGetFlags(_reachabilityRef, &flags)) 
 { 
 if (_alwaysReturnLocalWiFiStatus) 
 { 
  returnValue = [self localWiFiStatusForFlags:flags]; 
 } 
 else 
 { 
  returnValue = [self networkStatusForFlags:flags]; 
 } 
 } 
 return returnValue; 
} 
@end

AppDelegate中的实现:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
 //添加一个系统通知 
 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name:kReachabilityChangedNotification object:nil]; 
 //初始化 
 self.internetReachability=[Reachability reachabilityForInternetConnection]; 
 //通知添加到Run Loop 
 [self.internetReachability startNotifier]; 
 [self updateInterfaceWithReachability:_internetReachability]; 
 return YES; 
} 

回调函数:

(void) reachabilityChanged:(NSNotification *)note 
{ 
 Reachability* curReach = [note object]; 
 NSParameterAssert([curReach isKindOfClass:[Reachability class]]); 
 [self updateInterfaceWithReachability:curReach]; 
} 
- (void)updateInterfaceWithReachability:(Reachability *)reachability 
{ 
 NetworkStatus netStatus = [reachability currentReachabilityStatus]; 
 switch (netStatus) { 
 case NotReachable: 
  NSLog(@"====当前网络状态不可达=======http://www.cnblogs.com/xiaofeixiang"); 
  break; 
 case ReachableViaWiFi: 
  NSLog(@"====当前网络状态为Wifi=======博客园-Fly_Elephant"); 
  break; 
 case ReachableViaWWAN: 
  NSLog(@"====当前网络状态为3G=======keso"); 
  break; 
 } 
} 

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。


# ios实时检测网络状态  # ios  # 网络状态实时监控  # 实时监测网络状态  # iOS 检测网络状态的两种方法  # iOS实时监控网络状态的改变  # iOS中如何判断当前网络环境是2G/3G/4G/5G/WiFi  # iOS 12+ 中检测网络访问的方法  # 详解iOS AFNetworking取消正在进行的网络请求  # iOS中从网络获取数据的几种方法的比较  # iOS中多网络请求的线程安全详解  # iOS 本地视频和网络视频流播放实例代码  # 详解IOS判断当前网络状态的三种方法  # 可达  # 回调  # 是否能够  # 连上  # 自己的  # 离线  # 博客园  # 互联网  # 掉了  # 只显示  # 这篇文章  # 谢谢大家  # 多说  # 设置为  # 无图  # 也比  # 在工作中  # 中国  # 实时监控  # 说不定 


相关文章: 如何通过万网虚拟主机快速搭建网站?  怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?  网站制作与设计教程,如何制作一个企业网站,建设网站的基本步骤有哪些?  存储型VPS适合搭建中小型网站吗?  如何在云主机快速搭建网站站点?  建站168自助建站系统:快速模板定制与SEO优化指南  巅云智能建站系统:可视化拖拽+多端适配+免费模板一键生成  宝华建站服务条款解析:五站合一功能与SEO优化设置指南  网站网页制作专业公司,怎样制作自己的网页?  国美网站制作流程,国美电器蒸汽鍋怎么用官方网站?  如何在企业微信快速生成手机电脑官网?  网站制作报价单模板图片,小松挖机官方网站报价?  网站制作难吗安全吗,做一个网站需要多久时间?  小视频制作网站有哪些,有什么看国内小视频的网站,求推荐?  如何用VPS主机快速搭建个人网站?  猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?  广州网站设计制作一条龙,广州巨网网络科技有限公司是干什么的?  建站之星2.7模板快速切换与批量管理功能操作指南  长春网站建设制作公司,长春的网络公司怎么样主要是能做网站的?  网站制作免费,什么网站能看正片电影?  SAX解析器是什么,它与DOM在处理大型XML文件时有何不同?  ppt在线制作免费网站推荐,有什么下载免费的ppt模板网站?  如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?  建站之星后台搭建步骤解析:模板选择与产品管理实操指南  Dapper的Execute方法的返回值是什么意思 Dapper Execute返回值详解  如何通过可视化优化提升建站效果?  英语简历制作免费网站推荐,如何将简历翻译成英文?  建站之星与建站宝盒如何选择最佳方案?  深圳网站制作平台,深圳市做网站好的公司有哪些?  杭州银行网站设计制作流程,杭州银行怎么开通认证方式?  如何通过.red域名打造高辨识度品牌网站?  网站制作软件免费下载安装,有哪些免费下载的软件网站?  免费制作海报的网站,哪位做平面的朋友告诉我用什么软件做海报比较好?ps还是cd还是ai这几个软件我都会些我是做网页的?  制作充值网站的软件,做人力招聘为什么要自己交端口钱?  学校为何禁止电信移动建设网站?  企业微网站怎么做,公司网站和公众号有什么区别?  武汉外贸网站制作公司,现在武汉外贸前景怎么样啊?  Python路径拼接规范_跨平台处理说明【指导】  建站之家VIP精选网站模板与SEO优化教程整合指南  定制建站是什么?如何实现个性化需求?  如何通过云梦建站系统实现SEO快速优化?  如何选择域名并搭建高效网站?  宝塔建站无法访问?如何排查配置与端口问题?  太原网站制作公司有哪些,网约车营运证查询官网?  如何选择CMS系统实现快速建站与SEO优化?  湖州网站制作公司有哪些,浙江中蓝新能源公司官网?  制作公司内部网站有哪些,内网如何建网站?  小型网站建站如何选择虚拟主机?  制作企业网站建设方案,怎样建设一个公司网站?  家庭建站与云服务器建站,如何选择更优? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。