在douban应用中,需要联网是必须的,看书发现,apple对于需要联网的应用要求很高,必须要进行联网检查,现在还任务在身,但是忙中抽闲,看了看SCNetworkReachability,用于进行联网检查的。下面记录一下。
CFAllocatorRef allocator,
const struct sockaddr *address
CFAllocatorRef allocator,
const char *nodename
SCNetworkReachabilityRef target,
SCNetworkReachabilityFla gs *flags
回调示例:
触发实施网络状态查询示例:
realReachability架构概要图
说明引用网上网友的,特此注明、、、
一.基本知识
在需要联网的iPhone程序中,我们首先需要检查网络的状态,如果不能连接网络则告诉用户程序不能使用的原因是没有网络连接。在iPhone的SystemConfiguration框架里有提供了和联网相关的函数,可以用来检查网络的连接状态。
二.具体介绍
1.SCNetworkReachability介绍
SystemConfiguration框架中和测试网络连接状态相关的函数定义在SCNetworkReachability.H文件中,主要的函数有以下几个:
(1)创建测试连接的引用:
(a)SCNetworkReachabilityRef SCNetworkReachabilityCre ateWithAddress (
);
根据传入的地址测试连接,第一个参数可以为NULL或kCFAllocatorDefault,第二个参数为需要测试连接的IP地址,当为0.0.0.0时则可以查询本机的网络连接状态。同时返回一个引用必须在用完后释放。
(b)SCNetworkReachabilityRef SCNetworkReachabilityCre ateWithName (
);
这个是根据传入的网址测试连接,第二个参数比如为"www.apple.com",其他和上一个一样。
(2)确定连接的状态:
Boolean SCNetworkReachabilityGet Flags (
);
这个函数用来获得测试连接的状态,第一个参数为之前建立的测试连接的引用,第二个参数用来保存获得的状态,如果能获得状态则返回TRUE,否则返回FALSE
(3)主要的数据类型介绍:
SCNetworkReachabilityRef :用来保存创建测试连接返回的引用
(4)主要常量介绍:
SCNetworkReachabilityFla gs:保存返回的测试连接状态
其中常用的状态有:
kSCNetworkReachabilityFl agsReachable:能够连接网络
kSCNetworkReachabilityFl agsConnectionRequired:能够连接网络,但是首先得建立连接过程
kSCNetworkReachabilityFl agsIsWWAN:判断是否通过蜂窝网覆盖的连接,比如EDGE,GPRS或者目前的3G.主要是区别通过WiFi的连接。
2.代码例子
因此判断是否已经联网的代码例子可以如下所示:
+ (BOOL) connectedToNetwork
{
//创建零地址,0.0.0.0的地址表示查询本机的网络连接状态
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
// Recover reachability flags
SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCre ateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
SCNetworkReachabilityFla gs flags;
//获得连接的标志
BOOL didRetrieveFlags = SCNetworkReachabilityGet Flags(defaultRouteReachability , &flags);
CFRelease(defaultRouteReachability );
//如果不能获取连接标志,则不能连接网络,直接返回
if (!didRetrieveFlags)
{
return NO;
}
//根据获得的连接标志进行判断
BOOL isReachable = flags & kSCNetworkFlagsReachable ;
BOOL needsConnection = flags & kSCNetworkFlagsConnectio nRequired;
return (isReachable && !needsConnection) ? YES : NO;
}
集成和使用介绍
最简便的集成方法当前属性pod:pod 'RealReachability'
手动集成将文件夹导入
依赖:SystemConfiguration.framework
示例
开启监听:
- (void)viewDidLoad
{
[super viewDidLoad];
//创建GLobalRealReachability通知发送中心
[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));
if (status == RealStatusNotReachable)
{
self.flagLabel.text = @"Network unreachable!";
}
if (status == RealStatusViaWiFi)
{
self.flagLabel.text = @"Network wifi! Free!";
}
if (status == RealStatusViaWWAN)
{
self.flagLabel.text = @"Network WWAN! In charge!";
}
}
触发实施网络状态查询示例:
- (void)networkChanged:(NSNotification *)notification
{
RealReachability *reachability = (RealReachability *)notification.object;
ReachabilityStatus status = [reachability currentReachabilityStatus];
NSLog(@"currentStatus:%@",@(status));
if (status == RealStatusNotReachable)
{
self.flagLabel.text = @"Network unreachable!";
}
if (status == RealStatusViaWiFi)
{
self.flagLabel.text = @"Network wifi! Free!";
}
if (status == RealStatusViaWWAN)
{
self.flagLabel.text = @"Network WWAN! In charge!";
}
}
查询当前实际网络连接状态:
ReachabilityStatus status = [reachability currentReachabilityStatus];
realReachability架构概要图
RealReachability主要包含3大模块:connection、ping、FSM; 其中Ping模块通过对同样是苹果提供的ping样例代码进行了封装,connection模块实现了基于SCNetworkReachability的本地状态检测,FSM模块是有限状态机。通过FSM的状态管理控制connection模块和Ping模块协同工作,并通过可配置的定时策略等业务逻辑优化,最终得到了我们的实现。
PS:其中connection模块和ping模块也可独立使用,分别提供本地网络检测和ping的能力,感兴趣的读者也可以尝试(调用方式请参考RealReachability开源代码)。
PS:其中connection模块和ping模块也可独立使用,分别提供本地网络检测和ping的能力,感兴趣的读者也可以尝试(调用方式请参考RealReachability开源代码)。