-
-
Save darkseed/1182373 to your computer and use it in GitHub Desktop.
| /* | |
| File: Reachability.h | |
| Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs. | |
| Version: 2.2 - ARCified | |
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. | |
| ("Apple") in consideration of your agreement to the following terms, and your | |
| use, installation, modification or redistribution of this Apple software | |
| constitutes acceptance of these terms. If you do not agree with these terms, | |
| please do not use, install, modify or redistribute this Apple software. | |
| In consideration of your agreement to abide by the following terms, and subject | |
| to these terms, Apple grants you a personal, non-exclusive license, under | |
| Apple's copyrights in this original Apple software (the "Apple Software"), to | |
| use, reproduce, modify and redistribute the Apple Software, with or without | |
| modifications, in source and/or binary forms; provided that if you redistribute | |
| the Apple Software in its entirety and without modifications, you must retain | |
| this notice and the following text and disclaimers in all such redistributions | |
| of the Apple Software. | |
| Neither the name, trademarks, service marks or logos of Apple Inc. may be used | |
| to endorse or promote products derived from the Apple Software without specific | |
| prior written permission from Apple. Except as expressly stated in this notice, | |
| no other rights or licenses, express or implied, are granted by Apple herein, | |
| including but not limited to any patent rights that may be infringed by your | |
| derivative works or by other works in which the Apple Software may be | |
| incorporated. | |
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO | |
| WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED | |
| WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
| PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN | |
| COMBINATION WITH YOUR PRODUCTS. | |
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR | |
| CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE | |
| GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR | |
| DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF | |
| CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF | |
| APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| Copyright (C) 2010 Apple Inc. All Rights Reserved. | |
| */ | |
| #import <Foundation/Foundation.h> | |
| #import <SystemConfiguration/SystemConfiguration.h> | |
| struct sockaddr_in; | |
| typedef enum { | |
| NotReachable = 0, | |
| ReachableViaWiFi, | |
| ReachableViaWWAN | |
| } NetworkStatus; | |
| #define kReachabilityChangedNotification @"kNetworkReachabilityChangedNotification" | |
| @interface Reachability: NSObject | |
| //reachabilityWithHostName- Use to check the reachability of a particular host name. | |
| + (Reachability*) reachabilityWithHostName: (NSString*) hostName; | |
| //reachabilityWithAddress- Use to check the reachability of a particular IP address. | |
| + (Reachability*) reachabilityWithAddress: (const struct sockaddr_in*) hostAddress; | |
| //reachabilityForInternetConnection- checks whether the default route is available. | |
| // Should be used by applications that do not connect to a particular host | |
| + (Reachability*) reachabilityForInternetConnection; | |
| //reachabilityForLocalWiFi- checks whether a local wifi connection is available. | |
| + (Reachability*) reachabilityForLocalWiFi; | |
| //Start listening for reachability notifications on the current run loop | |
| - (BOOL) startNotifier; | |
| - (void) stopNotifier; | |
| - (NetworkStatus) currentReachabilityStatus; | |
| //WWAN may be available, but not active until a connection has been established. | |
| //WiFi may require a connection for VPN on Demand. | |
| - (BOOL) connectionRequired; | |
| @end | |
| /* | |
| File: Reachability.m | |
| Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs. | |
| Version: 2.2 - ARCified | |
| Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. | |
| ("Apple") in consideration of your agreement to the following terms, and your | |
| use, installation, modification or redistribution of this Apple software | |
| constitutes acceptance of these terms. If you do not agree with these terms, | |
| please do not use, install, modify or redistribute this Apple software. | |
| In consideration of your agreement to abide by the following terms, and subject | |
| to these terms, Apple grants you a personal, non-exclusive license, under | |
| Apple's copyrights in this original Apple software (the "Apple Software"), to | |
| use, reproduce, modify and redistribute the Apple Software, with or without | |
| modifications, in source and/or binary forms; provided that if you redistribute | |
| the Apple Software in its entirety and without modifications, you must retain | |
| this notice and the following text and disclaimers in all such redistributions | |
| of the Apple Software. | |
| Neither the name, trademarks, service marks or logos of Apple Inc. may be used | |
| to endorse or promote products derived from the Apple Software without specific | |
| prior written permission from Apple. Except as expressly stated in this notice, | |
| no other rights or licenses, express or implied, are granted by Apple herein, | |
| including but not limited to any patent rights that may be infringed by your | |
| derivative works or by other works in which the Apple Software may be | |
| incorporated. | |
| The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO | |
| WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED | |
| WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
| PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN | |
| COMBINATION WITH YOUR PRODUCTS. | |
| IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR | |
| CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE | |
| GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR | |
| DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF | |
| CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF | |
| APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| Copyright (C) 2010 Apple Inc. All Rights Reserved. | |
| */ | |
| #import <sys/socket.h> | |
| #import <netinet/in.h> | |
| #import <netinet6/in6.h> | |
| #import <arpa/inet.h> | |
| #import <ifaddrs.h> | |
| #import <netdb.h> | |
| #import <CoreFoundation/CoreFoundation.h> | |
| #import "Reachability.h" | |
| //#define kShouldPrintReachabilityFlags 1 | |
| static void PrintReachabilityFlags(SCNetworkReachabilityFlags flags, const char* comment) | |
| { | |
| #if kShouldPrintReachabilityFlags | |
| NSLog(@"Reachability Flag Status: %c%c %c%c%c%c%c%c%c %s\n", | |
| (flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-', | |
| (flags & kSCNetworkReachabilityFlagsReachable) ? 'R' : '-', | |
| (flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-', | |
| (flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-', | |
| (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? 'C' : '-', | |
| (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-', | |
| (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-', | |
| (flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 'l' : '-', | |
| (flags & kSCNetworkReachabilityFlagsIsDirect) ? 'd' : '-', | |
| comment | |
| ); | |
| #endif | |
| } | |
| static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info) | |
| { | |
| #pragma unused (target, flags) | |
| NSCAssert(info != NULL, @"info was NULL in ReachabilityCallback"); | |
| NSCAssert([(__bridge 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. | |
| @autoreleasepool { | |
| Reachability* noteObject = (__bridge Reachability*) info; | |
| // Post a notification to notify the client that the network reachability changed. | |
| [[NSNotificationCenter defaultCenter] postNotificationName: kReachabilityChangedNotification object: noteObject]; | |
| } | |
| } | |
| @implementation Reachability | |
| { | |
| BOOL localWiFiRef; | |
| SCNetworkReachabilityRef reachabilityRef; | |
| } | |
| - (BOOL)startNotifier | |
| { | |
| BOOL retVal = NO; | |
| SCNetworkReachabilityContext context = {0, (__bridge void *)self, NULL, NULL, NULL}; | |
| if(SCNetworkReachabilitySetCallback(reachabilityRef, ReachabilityCallback, &context)) | |
| { | |
| if(SCNetworkReachabilityScheduleWithRunLoop(reachabilityRef, CFRunLoopGetMain(), kCFRunLoopDefaultMode)) // DFH CFRunLoopGetCurrent() | |
| { | |
| retVal = YES; | |
| } | |
| } | |
| return retVal; | |
| } | |
| - (void)stopNotifier | |
| { | |
| if(reachabilityRef != NULL) | |
| { | |
| SCNetworkReachabilityUnscheduleFromRunLoop(reachabilityRef, CFRunLoopGetMain(), kCFRunLoopDefaultMode); // CFRunLoopGetCurrent() | |
| } | |
| } | |
| - (void) dealloc | |
| { | |
| [self stopNotifier]; | |
| if(reachabilityRef!= NULL) | |
| { | |
| CFRelease(reachabilityRef); | |
| } | |
| } | |
| + (Reachability*)reachabilityWithHostName: (NSString*) hostName; | |
| { | |
| Reachability* retVal = NULL; | |
| SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]); | |
| if(reachability!= NULL) | |
| { | |
| retVal= [[self alloc] init]; | |
| if(retVal!= NULL) | |
| { | |
| retVal->reachabilityRef = reachability; | |
| retVal->localWiFiRef = NO; | |
| } | |
| } | |
| return retVal; | |
| } | |
| + (Reachability*) reachabilityWithAddress: (const struct sockaddr_in*) hostAddress; | |
| { | |
| SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress); | |
| Reachability* retVal = NULL; | |
| if(reachability!= NULL) | |
| { | |
| retVal= [[self alloc] init]; | |
| if(retVal!= NULL) | |
| { | |
| retVal->reachabilityRef = reachability; | |
| retVal->localWiFiRef = NO; | |
| } | |
| } | |
| return retVal; | |
| } | |
| + (Reachability*) reachabilityForInternetConnection; | |
| { | |
| struct sockaddr_in zeroAddress; | |
| bzero(&zeroAddress, sizeof(zeroAddress)); | |
| zeroAddress.sin_len = sizeof(zeroAddress); | |
| zeroAddress.sin_family = AF_INET; | |
| return [self reachabilityWithAddress: &zeroAddress]; | |
| } | |
| + (Reachability*) reachabilityForLocalWiFi; | |
| { | |
| struct sockaddr_in localWifiAddress; | |
| bzero(&localWifiAddress, sizeof(localWifiAddress)); | |
| localWifiAddress.sin_len = sizeof(localWifiAddress); | |
| localWifiAddress.sin_family = AF_INET; | |
| // IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0 | |
| localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM); | |
| Reachability* retVal = [self reachabilityWithAddress: &localWifiAddress]; | |
| if(retVal!= NULL) | |
| { | |
| retVal->localWiFiRef = YES; | |
| } | |
| return retVal; | |
| } | |
| #pragma mark Network Flag Handling | |
| - (NetworkStatus) localWiFiStatusForFlags: (SCNetworkReachabilityFlags) flags | |
| { | |
| PrintReachabilityFlags(flags, "localWiFiStatusForFlags"); | |
| BOOL retVal = NotReachable; | |
| if((flags & kSCNetworkReachabilityFlagsReachable) && (flags & kSCNetworkReachabilityFlagsIsDirect)) | |
| { | |
| retVal = ReachableViaWiFi; | |
| } | |
| return retVal; | |
| } | |
| - (NetworkStatus) networkStatusForFlags: (SCNetworkReachabilityFlags) flags | |
| { | |
| PrintReachabilityFlags(flags, "networkStatusForFlags"); | |
| if ((flags & kSCNetworkReachabilityFlagsReachable) == 0) | |
| { | |
| // if target host is not reachable | |
| return NotReachable; | |
| } | |
| BOOL retVal = NotReachable; | |
| if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0) | |
| { | |
| // if target host is reachable and no connection is required | |
| // then we'll assume (for now) that your on Wi-Fi | |
| retVal = ReachableViaWiFi; | |
| } | |
| if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) || | |
| (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0)) | |
| { | |
| // ... and the connection is on-demand (or on-traffic) if the | |
| // calling application is using the CFSocketStream or higher APIs | |
| if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0) | |
| { | |
| // ... and no [user] intervention is needed | |
| retVal = ReachableViaWiFi; | |
| } | |
| } | |
| if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN) | |
| { | |
| // ... but WWAN connections are OK if the calling application | |
| // is using the CFNetwork (CFSocketStream?) APIs. | |
| retVal = ReachableViaWWAN; | |
| } | |
| return retVal; | |
| } | |
| - (BOOL)connectionRequired; | |
| { | |
| NSAssert(reachabilityRef != NULL, @"connectionRequired called with NULL reachabilityRef"); | |
| SCNetworkReachabilityFlags flags; | |
| if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) | |
| { | |
| return (flags & kSCNetworkReachabilityFlagsConnectionRequired); | |
| } | |
| return NO; | |
| } | |
| - (NetworkStatus)currentReachabilityStatus | |
| { | |
| NSAssert(reachabilityRef != NULL, @"currentNetworkStatus called with NULL reachabilityRef"); | |
| NetworkStatus retVal = NotReachable; | |
| SCNetworkReachabilityFlags flags; | |
| if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) | |
| { | |
| if(localWiFiRef) | |
| { | |
| retVal = [self localWiFiStatusForFlags: flags]; | |
| } | |
| else | |
| { | |
| retVal = [self networkStatusForFlags: flags]; | |
| } | |
| } | |
| return retVal; | |
| } | |
| @end |
Thanks a lot for your work! I was disappointed with iOS5 & Reachability :s
Just a little remark:
When you write that: retVal= [[self alloc] init];
(lines 139 & 155)
there are potential leaks, no?
Corrected with an autorelease for example.
It's meant to be used with ARC. ARC will automatically release retVal.
Sorry, I was passed over the ARCified, tired... :)
No worries!
Thanks!
This one looks great too: https://github.com/tonymillion/Reachability
In the callback method,
static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info),
why aren't the flags used? Can't we just stuff it into the Reachability object instead of doing another call SCNetworkReachabilityGetFlags when we wish to determine the network status?
Thanks :)
Thanks! Great!
Good Work!
Thanks!
Thanks, it saved time
Thanks, It saved me.... ;)
Thanks, It saved me.... ;)
Has anyone encountered SIGPIPE terminations caused by this code?
Thanks loads for this!!!!!!!