Reachability
Apple 的 例程 Reachability 中介绍了取得/检测网络状态的方法。在你的程序中使用 Reachability 只须将该例程中的 Reachability.h 和 Reachability.m 拷贝到你的工程中。如下图:
然后将 SystemConfiguration.framework 添加进工程:
Reachability 中全局定义了3种网络状态,定义了一个消息名字(在未来的消费class中也会通过这个检测消息):
typedefenum {
NotReachable =0,
ReachableViaWiFi,
ReachableViaWWAN
} NetworkStatus;
#define kReachabilityChangedNotification @"kNetworkReachabilityChangedNotification"
高级网络判断
//WWAN may be available, but not active until a connection has been established.
//WiFi may require a connection for VPN on Demand.
- (BOOL) connectionRequired;
//
- static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info)
- {
- #pragma unused (target, flags)
- NSCAssert(info != NULL, @"info was NULL in ReachabilityCallback");
- NSCAssert([(NSObject*) info isKindOfClass: [Reachability class]], @"info was wrong class in ReachabilityCallback");
- //We're on the main RunLoop, so an NSAutoreleasePool is not necessary, but is added defensively
- // in case someon uses the Reachablity object in a different thread.
- NSAutoreleasePool* myPool = [[NSAutoreleasePool alloc] init];
- Reachability* noteObject = (Reachability*) info;
- //
- // Post a notification to notify the client that the network reachability changed.
- [[NSNotificationCenter <span style="color: rgb(255, 102, 102);">defaultCenter</span>] postNotificationName: kReachabilityChangedNotification object: noteObject];
- //可以充分使用这
- [myPool release];
- }
- - (BOOL) startNotifier
- {
- BOOL retVal = NO;
- SCNetworkReachabilityContext context = {0, self, NULL, NULL, NULL};
- //TRUE if the notification client was successfully set。。。。
- if(SCNetworkReachabilitySetCallback(reachabilityRef, ReachabilityCallback, &context))
- { //特定的runloop
- if(SCNetworkReachabilityScheduleWithRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode))
- {
- retVal = YES;
- }
- }
- return retVal;
- }
- - (void) stopNotifier
- {
- if(reachabilityRef!= NULL)
- {
- SCNetworkReachabilityUnscheduleFromRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
- }
- }
static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info)
{
#pragma unused (target, flags)
NSCAssert(info != NULL, @"info was NULL in ReachabilityCallback");
NSCAssert([(NSObject*) info isKindOfClass: [Reachability class]], @"info was wrong class in ReachabilityCallback");
//We're on the main RunLoop, so an NSAutoreleasePool is not necessary, but is added defensively
// in case someon uses the Reachablity object in a different thread.
NSAutoreleasePool* myPool = [[NSAutoreleasePool alloc] init];
Reachability* noteObject = (Reachability*) info;
//
// Post a notification to notify the client that the network reachability changed.
[[NSNotificationCenter defaultCenter] postNotificationName: kReachabilityChangedNotification object: noteObject];
//可以充分使用这
[myPool release];
}
- (BOOL) startNotifier
{
BOOL retVal = NO;
SCNetworkReachabilityContext context = {0, self, NULL, NULL, NULL};
//TRUE if the notification client was successfully set。。。。
if(SCNetworkReachabilitySetCallback(reachabilityRef, ReachabilityCallback, &context))
{ //特定的runloop
if(SCNetworkReachabilityScheduleWithRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode))
{
retVal = YES;
}
}
return retVal;
}
- (void) stopNotifier
{
if(reachabilityRef!= NULL)
{
SCNetworkReachabilityUnscheduleFromRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
}
}
可以看到示范代码考虑得非常细,通过callback然后postnotification;使用
[[NSNotificationCenterdefaultCenter] addObserver:self selector: @selector(reachabilityChanged:)name: kReachabilityChangedNotificationobject: nil];
Here is a checklist for integrating an observer for the connection:
- Get the Reachability class from Apple, it has all the functionality we need to check if a connection is up/down
- Import the class into your app
- Initialize it and create an observer
- Create a method that handles an alteration of the network status