Skip to content

Instantly share code, notes, and snippets.

@zonble
Created May 25, 2009 06:04
Show Gist options
  • Save zonble/117402 to your computer and use it in GitHub Desktop.
Save zonble/117402 to your computer and use it in GitHub Desktop.
@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);
#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