Created
May 25, 2009 06:04
-
-
Save zonble/117402 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@class LFReachability; | |
typedef enum { | |
LFReachabilityNetworkNone = 0, | |
LFReachabilityNetworkWifi = 1, | |
LFReachabilityNetworkWWAN = 2 | |
} LFReachabilityNetworkType; | |
@protocol LFReachabilityDelegate <NSObject> | |
- (void)reachability:(LFReachability *)inReachability networkIsReachable:(LFReachabilityNetworkType)type; | |
- (void)reachabilityNetworkIsNotReachable:(LFReachability *)inReachability; | |
@end | |
@interface LFReachability : NSObject | |
{ | |
id <LFReachabilityDelegate> _delegate; | |
SCNetworkReachabilityRef reachability; | |
NSTimer *_waitTimer; | |
NSTimeInterval _timeOut; | |
} | |
+ (LFReachability *)sharedReachability; | |
- (void)checkReachabilityWithDelegate:(id)delegate; | |
- (void)setNetworkIsReachableWithFlag:(SCNetworkReachabilityFlags)flag; | |
- (void)setNetworkIsNotReachable; | |
- (void)clearTimer; | |
@property (readonly) id delegate; | |
@property (assign) NSTimeInterval timeOut; | |
@end | |
void MyReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *info); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <sys/types.h> | |
#import <sys/socket.h> | |
#import <netdb.h> | |
#import <arpa/inet.h> | |
#import "LFReachability.h" | |
static LFReachability *reachability; | |
@implementation LFReachability | |
+ (LFReachability *)sharedReachability | |
{ | |
if (!reachability) { | |
reachability = [[LFReachability alloc] init]; | |
} | |
return reachability; | |
} | |
- (void) dealloc | |
{ | |
_delegate = nil; | |
[super dealloc]; | |
} | |
- (id)init | |
{ | |
self = [super init]; | |
if (self != nil) { | |
_delegate = nil; | |
_timeOut = 5.0; | |
} | |
return self; | |
} | |
- (void)timerFireMethod:(NSTimer*)theTimer | |
{ | |
[self clearTimer]; | |
[self setNetworkIsNotReachable]; | |
// CFRelease(reachability); | |
} | |
- (void)clearTimer | |
{ | |
if (_waitTimer) { | |
[_waitTimer invalidate]; | |
[_waitTimer release]; | |
_waitTimer = nil; | |
} | |
} | |
- (void)setNetworkIsReachableWithFlag:(SCNetworkReachabilityFlags)flag; | |
{ | |
if (reachability) { | |
CFRunLoopRef runLoop = CFRunLoopGetCurrent(); | |
SCNetworkReachabilityUnscheduleFromRunLoop(reachability, runLoop, kCFRunLoopCommonModes); | |
CFRelease(reachability); | |
reachability = NULL; | |
} | |
LFReachabilityNetworkType type; | |
// NSLog(@"flag:%X", flag); | |
if (flag & kSCNetworkReachabilityFlagsIsWWAN) { | |
type = LFReachabilityNetworkWWAN; | |
} | |
else { | |
type = LFReachabilityNetworkWifi; | |
} | |
if ([_delegate respondsToSelector:@selector(reachability:reachability:)]) { | |
[_delegate reachability:self networkIsReachable:type]; | |
} | |
NSLog(@"reachability:%d", type); | |
// | |
} | |
- (void)setNetworkIsNotReachable | |
{ | |
if (reachability) { | |
CFRunLoopRef runLoop = CFRunLoopGetCurrent(); | |
SCNetworkReachabilityUnscheduleFromRunLoop(reachability, runLoop, kCFRunLoopCommonModes); | |
CFRelease(reachability); | |
reachability = NULL; | |
} | |
if ([_delegate respondsToSelector:@selector(reachabilityNetworkIsNotReachable:)]) { | |
[_delegate reachabilityNetworkIsNotReachable:self]; | |
} | |
NSLog(@"setNetworkIsNotReachable"); | |
} | |
- (void)checkReachabilityWithDelegate:(id)delegate | |
{ | |
_delegate = delegate; | |
[self clearTimer]; | |
// Create zero addy | |
struct sockaddr_in zeroAddress; | |
bzero(&zeroAddress, sizeof(zeroAddress)); | |
zeroAddress.sin_len = sizeof(zeroAddress); | |
zeroAddress.sin_family = AF_INET; | |
if (reachability) { | |
CFRunLoopRef runLoop = CFRunLoopGetCurrent(); | |
SCNetworkReachabilityUnscheduleFromRunLoop(reachability, runLoop, kCFRunLoopCommonModes); | |
CFRelease(reachability); | |
reachability = NULL; | |
} | |
reachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress); | |
SCNetworkReachabilityFlags flags; | |
BOOL b = SCNetworkReachabilityGetFlags(reachability, &flags); | |
if (b) { | |
if ((flags & kSCNetworkReachabilityFlagsReachable) && !(flags & kSCNetworkReachabilityFlagsConnectionRequired)) { | |
[self setNetworkIsReachableWithFlag:flags]; | |
return; | |
} | |
} | |
SCNetworkReachabilityContext context = {0, self, NULL, NULL, NULL}; | |
SCNetworkReachabilitySetCallback(reachability, MyReachabilityCallback, &context); | |
CFRunLoopRef runLoop = CFRunLoopGetCurrent(); | |
SCNetworkReachabilityScheduleWithRunLoop(reachability, runLoop, kCFRunLoopCommonModes); | |
_waitTimer = [NSTimer scheduledTimerWithTimeInterval:_timeOut target:self selector:@selector(timerFireMethod:) userInfo:NULL repeats:NO]; | |
[_waitTimer retain]; | |
} | |
@synthesize delegate = _delegate; | |
@synthesize timeOut = _timeOut; | |
@end | |
void MyReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *info) | |
{ | |
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | |
[[LFReachability sharedReachability] clearTimer]; | |
if ((flags & kSCNetworkReachabilityFlagsReachable) && !(flags & kSCNetworkReachabilityFlagsConnectionRequired)) { | |
[[LFReachability sharedReachability] setNetworkIsReachableWithFlag:flags]; | |
} | |
else { | |
[[LFReachability sharedReachability] setNetworkIsNotReachable]; | |
} | |
CFRelease(target); | |
[pool release]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment