全网整合营销服务商

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

免费咨询热线: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判断当前网络状态的三种方法  # 可达  # 回调  # 是否能够  # 连上  # 自己的  # 离线  # 博客园  # 互联网  # 掉了  # 只显示  # 这篇文章  # 谢谢大家  # 多说  # 设置为  # 无图  # 也比  # 在工作中  # 中国  # 实时监控  # 说不定 


相关文章: 手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?  如何在企业微信快速生成手机电脑官网?  定制建站流程步骤详解:一站式方案设计与开发指南  威客平台建站流程解析:高效搭建教程与设计优化方案  网站制作外包价格怎么算,招聘网站上写的“外包”是什么意思?  宝盒自助建站智能生成技巧:SEO优化与关键词设置指南  GML (Geography Markup Language)是什么,它如何用XML来表示地理空间信息?  网站制作说明怎么写,简述网页设计的流程并说明原因?  如何挑选最适合建站的高性能VPS主机?  如何选择适合PHP云建站的开源框架?  手机怎么制作网站教程步骤,手机怎么做自己的网页链接?  股票网站制作软件,网上股票怎么开户?  装修招标网站设计制作流程,装修招标流程?  深圳网站制作的公司有哪些,dido官方网站?  如何选择网络建站服务器?高效建站必看指南  制作充值网站的软件,做人力招聘为什么要自己交端口钱?  网站制作公司,橙子建站是合法的吗?  如何在云主机上快速搭建多站点网站?  建站主机是否等同于虚拟主机?  如何制作一个表白网站视频,关于勇敢表白的小标题?  枣阳网站制作,阳新火车站打的到仙岛湖多少钱?  免费网站制作模板下载,除了易企秀之外还有什么H5平台可以制作H5长页面,最好是免费的?  建站之星官网登录失败?如何快速解决?  南平网站制作公司,2025年南平市事业单位报名时间?  如何在Windows虚拟主机上快速搭建网站?  中山网站制作网页,中山新生登记系统登记流程?  英语简历制作免费网站推荐,如何将简历翻译成英文?  nginx修改上传文件大小限制的方法  武汉外贸网站制作公司,现在武汉外贸前景怎么样啊?  深圳防火门网站制作公司,深圳中天明防火门怎么编码?  如何解决ASP生成WAP建站中文乱码问题?  宁波自助建站系统如何快速打造专业企业网站?  logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?  做企业网站制作流程,企业网站制作基本流程有哪些?  模具网站制作流程,如何找模具客户?  如何通过.red域名打造高辨识度品牌网站?  如何在建站之星网店版论坛获取技术支持?  如何正确选择百度移动适配建站域名?  如何在腾讯云免费申请建站?  内部网站制作流程,如何建立公司内部网站?  网站制作难吗安全吗,做一个网站需要多久时间?  c# Task.ConfigureAwait(true) 在什么场景下是必须的  网站制作新手教程,新手建设一个网站需要注意些什么?  制作网站建设的公司有哪些,网站建设比较好的公司都有哪些?  深圳网站制作费用多少钱,读秀,深圳文献港这样的网站很多只提供网上试读,但有些人只要提供试读的文章就能全篇下载,这个是怎么弄的?  网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?  C#怎么创建控制台应用 C# Console App项目创建方法  微信小程序制作网站有哪些,微信小程序需要做网站吗?  如何通过山东自助建站平台快速注册域名?  如何用y主机助手快速搭建网站? 

您的项目需求

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