iOS实现实时检测网络状态的示例代码
发布时间 - 2026-01-11 02:19:55 点击率:次前言

在网络应用中,需要对用户设备的网络状态进行实时监控,有两个目的:
(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判断当前网络状态的三种方法
# 可达
# 回调
# 是否能够
# 连上
# 自己的
# 离线
# 博客园
# 互联网
# 掉了
# 只显示
# 这篇文章
# 谢谢大家
# 多说
# 设置为
# 无图
# 也比
# 在工作中
# 中国
# 实时监控
# 说不定
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
免费网站制作appp,免费制作app哪个平台好?
html5如何设置样式_HTML5样式设置方法与CSS应用技巧【教程】
微信小程序 wx.uploadFile无法上传解决办法
Laravel如何实现邮件验证激活账户_Laravel内置MustVerifyEmail接口配置【步骤】
Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道
如何在腾讯云免费申请建站?
头像制作网站在线观看,除了站酷,还有哪些比较好的设计网站?
如何用5美元大硬盘VPS安全高效搭建个人网站?
Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】
教你用AI润色文章,让你的文字表达更专业
奇安信“盘古石”团队突破 iOS 26.1 提权
详解Huffman编码算法之Java实现
Laravel如何实现全文搜索_Laravel Scout集成Algolia或Meilisearch教程
linux top下的 minerd 木马清除方法
Win11摄像头无法使用怎么办_Win11相机隐私权限开启教程【详解】
如何快速生成凡客建站的专业级图册?
如何用JavaScript实现文本编辑器_光标和选区怎么处理
Python文本处理实践_日志清洗解析【指导】
米侠浏览器网页图片不显示怎么办 米侠图片加载修复
php打包exe后无法访问网络共享_共享权限设置方法【教程】
php8.4header发送头信息失败怎么办_php8.4header函数问题解决【解答】
高端建站如何打造兼具美学与转化的品牌官网?
悟空识字怎么关闭自动续费_悟空识字取消会员自动扣费步骤
智能起名网站制作软件有哪些,制作logo的软件?
音响网站制作视频教程,隆霸音响官方网站?
浅述节点的创建及常见功能的实现
齐河建站公司:营销型网站建设与SEO优化双核驱动策略
谷歌浏览器如何更改浏览器主题 Google Chrome主题设置教程
phpredis提高消息队列的实时性方法(推荐)
php读取心率传感器数据怎么弄_php获取max30100的心率值【指南】
文字头像制作网站推荐软件,醒图能自动配文字吗?
制作公司内部网站有哪些,内网如何建网站?
html5源代码发行怎么设置权限_访问权限控制方法与实践【指南】
专业型网站制作公司有哪些,我设计专业的,谁给推荐几个设计师兼职类的网站?
制作企业网站建设方案,怎样建设一个公司网站?
Laravel Eloquent关联是什么_Laravel模型一对一与一对多关系精讲
JavaScript如何操作视频_媒体API怎么控制播放
如何自定义建站之星模板颜色并下载新样式?
JavaScript中的标签模板是什么_它如何扩展字符串功能
Laravel如何设置自定义的日志文件名_Laravel根据日期或用户ID生成动态日志【技巧】
手机网站制作与建设方案,手机网站如何建设?
Laravel如何配置.env文件管理环境变量_Laravel环境变量使用与安全管理
Laravel如何连接多个数据库_Laravel多数据库连接配置与切换教程
javascript读取文本节点方法小结
Windows10如何更改计算机工作组_Win10系统属性修改Workgroup
如何在HTML表单中获取用户输入并用JavaScript动态控制复利计算循环
如何用花生壳三步快速搭建专属网站?
Android仿QQ列表左滑删除操作
Laravel如何发送系统通知_Laravel Notifications实现多渠道消息通知
nodejs redis 发布订阅机制封装实现方法及实例代码

