iOS下的实际网络连接状态检测(转)
序言
网络连接状态检测对于我们的iOS app开发来说是一个非常通用的需求。为了更好的用户体验,我们会在无网络时展现本地或者缓存的内容,并对用户进行合适的提示。对绝大部分iOS开发者来说,从苹果示例代码改变而来的各种Reachablity框架是实现这个需求的普遍选择,比如这个库。但事实上,基于此方案的所有实现,都无法帮助我们检测真正的网络连接状态,它们能检测的只是本地连接状态;这种情况包括但不限于如下场景:
1.现在很流行的公用wifi,需要网页鉴权,鉴权之前无法上网,但本地连接已经建立;
2.存在了本地网络连接,但信号很差,实际无法连接到服务器;
3.iOS连接的路由设备本身没有连接外网。
CocoaChina上已有很多网友对此进行提问和吐槽,比如:
如何判断设备是否真正连上互联网?而不是只有网络连接
[Reachability reachabilityWithHostName:]完全没用!
苹果的Reachability示例中有如下说明,告诉我们其能力受限于此:
"Reachability cannot tell your application if you can connect to a particular host, only that an interface is available that might allow a connection, and whether that interface is the WWAN."
而苹果的SCNetworkReachability API则告诉了我们更多: "Reachability does not guarantee that the data packet will actually be received by the host. "
Reachability相关的框架在底层都是通过SCNetworkReachability来实现网络检测的,所以无法检测实际网络连接情况。
有鉴于此,笔者希望打造一个通用、简单、可靠的实际网络连接状态检测框架,于是RealReachability诞生了。
RealReachability简单介绍
RealReachability是笔者1个月之前发布到github的开源库,项目地址如下: https://github.com/dustturtle/RealReachability 短短1个月时间收获了100多个star,其中主要来自于外国友人,最近还上了github的OC板块趋势排行榜,着实令笔者相当惊喜。 此框架开发的初衷来源于项目实际需求,离线模式对网络连接状态的要求比较苛刻,且实际场景经常会遇到“伪连接”的情况,Reachability面对此场景力不从心。多方研究后引入了ping能力(此方案流量开销最小,也最简单),实现了简单的实际网络连接监测;后面经过提炼和优化,就有了这个框架。可以告诉大家的是,这个框架在appstore上架应用中已经经受了考验,且经过了长时间的测试,可以放心使用。
集成和使用介绍
集成
最简便的集成方法当属pod: pod 'RealReachability'。
手动集成:将RealReachability文件夹加入到工程即可。
依赖:Xcode5.0+,支持ARC, iOS6+.项目需要引入SystemConfiguration.framework.
使用介绍
其接口的设计和调用方法和Reachability非常相似,大家可以无缝上手,非常方便。 开启网络监听:
[GLobalRealReachability startNotifier];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(networkChanged:)
name:kRealReachabilityChangedNotification
object:nil];
回调代码示例:
- (void)networkChanged:(NSNotification *)notification
{
RealReachability *reachability = (RealReachability *)notification.object;
ReachabilityStatus status = [reachability currentReachabilityStatus];
NSLog(@"currentStatus:%@",@(status));
}
触发实时网络状态查询代码示例:
[GLobalRealReachability reachabilityWithBlock:^(ReachabilityStatus status) {
switch (status)
{
case NotReachable:
{
// case NotReachable handler
break;
}
case ReachableViaWiFi:
{
// case ReachableViaWiFi handler
break;
}
case ReachableViaWWAN:
{
// case ReachableViaWWAN handler
break;
}
default:
break;
}
}];
查询当前实际网络连接状态:
ReachabilityStatus status = [reachability currentReachabilityStatus];
Demo:
我们在github的repository中已经包含了简单的Demo工程,直接下载运行即可。相关的Api调用也可以参考demo中的实现。 demo截图:

45.png
RealReachability的实现原理
RealReachability架构图:

111.png
realReachability架构概要图RealReachability主要包含3大模块:connection、ping、FSM; 其中Ping模块通过对同样是苹果提供的ping样例代码进行了封装,connection模块实现了基于SCNetworkReachability的本地状态检测,FSM模块是有限状态机。通过FSM的状态管理控制connection模块和Ping模块协同工作,并通过可配置的定时策略等业务逻辑优化,最终得到了我们的实现。
PS:其中connection模块和ping模块也可独立使用,分别提供本地网络检测和ping的能力,感兴趣的读者也可以尝试(调用方式请参考RealReachability开源代码)。
结束语
希望这个框架能够帮助到大家的iOS开发! 遇到任何疑问或者使用上的问题,都可以联系我。
对此框架我也会持续进行维护和优化,更希望感兴趣的朋友可以到github上pull request! 开源有你更精彩! https://github.com/dustturtle/RealReachability 觉得有用就点个star喔!
iOS下的实际网络连接状态检测(转)的更多相关文章
- 李洪强iOS下的实际网络连接状态检测
iOS下的实际网络连接状态检测 序言 网络连接状态检测对于我们的iOS app开发来说是一个非常通用的需求.为了更好的用户体验,我们会在无网络时展现本地或者缓存的内容,并对用户进行合适的提示.对绝大部 ...
- vm虚拟机里的桥接模式下“复制物理网络连接状态”作用
前提:真实主机可以上网 勾选,虚拟机也可以上网 不勾选,虚拟机不可以上网
- iOS开发 - Swift实现检测网络连接状态及网络类型
一.前言 在移动开发中,检测网络的连接状态尤其检测网络的类型尤为重要.本文将介绍在iOS开发中,如何使用Swift检测网络连接状态及网络类型(移动网络.Wifi). 二.如何实现 Reachabili ...
- [Swift通天遁地]四、网络和线程-(6)检测网络连接状态
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- Android 检测网络连接状态
Android连接网络的时候,并不是每次都能连接到网络,因此在程序启动中需要对网络的状态进行判断,如果没有网络则提醒用户进行设置. 首先,要判断网络状态,需要有相应的权限,下面为权限代码(Androi ...
- Delphi检测网络连接状态
有时候,我们做一些小软件就需要检测网络连接状态,比如想给你的软件加上类似QQ那样的系统消息,可是像我这样的穷人肯定是买不起服务器了,那我们只好另想办法,可以读取网页然后用浏览器显示,这个时候就需要判断 ...
- android检测网络连接状态示例讲解
网络的时候,并不是每次都能连接到网络,因此在程序启动中需要对网络的状态进行判断,如果没有网络则提醒用户进行设置 Android连接首先,要判断网络状态,需要有相应的权限,下面为权限代码(Andro ...
- CentOS下netstat + awk 查看tcp的网络连接状态
执行以下命令: #netstat -n | awk ‘/^tcp/ {++state[$NF]} END {for(key in state) print key."\t".sta ...
- iOS 如何判断当前网络连接状态 网络是否正常 网络是否可用
网络资源:出处http://blog.csdn.net/mad1989/article/details/8987368 众所周知,我们在开发APP时,涉及网络连接的时候,都会想着提前判断一下当前的 ...
随机推荐
- 记录ASP.NET页面表单初始状态(主要是为了前台可以根据这个判断页面是否变动了)
把页面表单状态记录到HiddenField中. 这里只提供后台代码, 前台逻辑根据需求自由定义. 存放值的ViewState: protected Dictionary<string, stri ...
- 未找到具有固定名称“System.Data.SQLite”的 ADO.NET 提供程序的实体框架提供程序
用户代码未处理 System.InvalidOperationException HResult=-2146233079 Message=未找到具有固定名称"System.Data. ...
- javascript动态创建对象
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Chrome和Firefox浏览器调试对比
最近的项目中使用Extjs5, 其中主要的一个特点就是js文件的动态加载,之前使用Firefox浏览器对js文件进行调试,打断点时,只对当次调试有效,刷新之后,由于动态加载的js文件(文件名后面加了一 ...
- 加密html
2009年4月4日 周六 22:18 <HTML> <HEAD> <meta http-equiv="Content-Type" content=&q ...
- Ubuntu下安装arm-linux-gcc
安装步骤: 这里采用友善之臂发布的arm-linux-gcc-4.4.3.tar.gz软件包. 一.将压缩包arm-linux-gcc-4.4.3.tar.gz存放在opt目录下. 执行解压命令:su ...
- HtmlParser基础教程
1.相关资料 官方文档:http://htmlparser.sourceforge.net/samples.html API:http://htmlparser.sourceforge.net/jav ...
- Apache无法启动解决方案
Apache无法启动错误原因: 原因一:80端口占用例如IIS,另外就是迅雷.我的apache服务器就是被迅雷害得无法启用! 原因二:软件冲突装了某些软件会使apache无法启动如Dr.com 你打开 ...
- ssh username@10.2.1.23无法连接
ssh username@10.2.1.23无法连接 经过排查各种openSSH版本等,最终因为两个机器不是一个段(A:255.255.0.0 B:255.255.255.0)造成的. 关于IP需要以 ...
- PowerDesigner中NAME和COMMENT的互相转换,需要执行语句
原文: http://www.cnblogs.com/xnxylf/p/3288718.html 由于PDM 的表中 Name 会默认=Code 所以很不方便, 所以需要将 StereoType 显示 ...