/WebServiceDemo/Required_Libs/HTTPRequest/External/Reachability/Reachability.m
Objective C | 814 lines | 378 code | 278 blank | 158 comment | 50 complexity | ee39cbaee5f108bf1aee3c76984102f0 MD5 | raw file
- /*
-
- File: Reachability.m
- Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs.
-
- Version: 2.0.4ddg
- */
- /*
- Significant additions made by Andrew W. Donoho, August 11, 2009.
- This is a derived work of Apple's Reachability v2.0 class.
-
- The below license is the new BSD license with the OSI recommended personalizations.
- <http://www.opensource.org/licenses/bsd-license.php>
- Extensions Copyright (C) 2009 Donoho Design Group, LLC. All Rights Reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of Andrew W. Donoho nor Donoho Design Group, L.L.C.
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY DONOHO DESIGN GROUP, L.L.C. "AS IS" AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- */
- /*
-
- Apple's Original License on Reachability v2.0
-
- 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) 2009 Apple Inc. All Rights Reserved.
-
- */
- /*
- Each reachability object now has a copy of the key used to store it in a dictionary.
- This allows each observer to quickly determine if the event is important to them.
- */
- #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"
- NSString *const kInternetConnection = @"InternetConnection";
- NSString *const kLocalWiFiConnection = @"LocalWiFiConnection";
- NSString *const kReachabilityChangedNotification = @"NetworkReachabilityChangedNotification";
- #define CLASS_DEBUG 1 // Turn on logReachabilityFlags. Must also have a project wide defined DEBUG.
- #if (defined DEBUG && defined CLASS_DEBUG)
- #define logReachabilityFlags(flags) (logReachabilityFlags_(__PRETTY_FUNCTION__, __LINE__, flags))
- static NSString *reachabilityFlags_(SCNetworkReachabilityFlags flags) {
-
- #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 30000) // Apple advises you to use the magic number instead of a symbol.
- return [NSString stringWithFormat:@"Reachability Flags: %c%c %c%c%c%c%c%c%c",
- (flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-',
- (flags & kSCNetworkReachabilityFlagsReachable) ? 'R' : '-',
-
- (flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-',
- (flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-',
- (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
- (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? 'C' : '-',
- (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-',
- (flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 'l' : '-',
- (flags & kSCNetworkReachabilityFlagsIsDirect) ? 'd' : '-'];
- #else
- // Compile out the v3.0 features for v2.2.1 deployment.
- return [NSString stringWithFormat:@"Reachability Flags: %c%c %c%c%c%c%c%c",
- (flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-',
- (flags & kSCNetworkReachabilityFlagsReachable) ? 'R' : '-',
-
- (flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-',
- (flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-',
- (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
- // v3 kSCNetworkReachabilityFlagsConnectionOnTraffic == v2 kSCNetworkReachabilityFlagsConnectionAutomatic
- (flags & kSCNetworkReachabilityFlagsConnectionAutomatic) ? 'C' : '-',
- // (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-', // No v2 equivalent.
- (flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 'l' : '-',
- (flags & kSCNetworkReachabilityFlagsIsDirect) ? 'd' : '-'];
- #endif
-
- } // reachabilityFlags_()
- static void logReachabilityFlags_(const char *name, int line, SCNetworkReachabilityFlags flags) {
-
- NSLog(@"%s (%d) \n\t%@", name, line, reachabilityFlags_(flags));
-
- } // logReachabilityFlags_()
- #define logNetworkStatus(status) (logNetworkStatus_(__PRETTY_FUNCTION__, __LINE__, status))
- static void logNetworkStatus_(const char *name, int line, NetworkStatus status) {
-
- NSString *statusString = nil;
-
- switch (status) {
- case kNotReachable:
- statusString = [NSString stringWithString: @"Not Reachable"];
- break;
- case kReachableViaWWAN:
- statusString = [NSString stringWithString: @"Reachable via WWAN"];
- break;
- case kReachableViaWiFi:
- statusString = [NSString stringWithString: @"Reachable via WiFi"];
- break;
- }
-
- NSLog(@"%s (%d) \n\tNetwork Status: %@", name, line, statusString);
-
- } // logNetworkStatus_()
- #else
- #define logReachabilityFlags(flags)
- #define logNetworkStatus(status)
- #endif
- @interface Reachability (private)
- - (NetworkStatus) networkStatusForFlags: (SCNetworkReachabilityFlags) flags;
- @end
- @implementation Reachability
- @synthesize key = key_;
- // Preclude direct access to ivars.
- + (BOOL) accessInstanceVariablesDirectly {
-
- return NO;
- } // accessInstanceVariablesDirectly
- - (void) dealloc {
-
- [self stopNotifier];
- if(reachabilityRef) {
-
- CFRelease(reachabilityRef); reachabilityRef = NULL;
-
- }
-
- self.key = nil;
-
- [super dealloc];
-
- } // dealloc
- - (Reachability *) initWithReachabilityRef: (SCNetworkReachabilityRef) ref
- {
- self = [super init];
- if (self != nil)
- {
- reachabilityRef = ref;
- }
-
- return self;
-
- } // initWithReachabilityRef:
- #if (defined DEBUG && defined CLASS_DEBUG)
- - (NSString *) description {
-
- NSAssert(reachabilityRef, @"-description called with NULL reachabilityRef");
-
- SCNetworkReachabilityFlags flags = 0;
-
- SCNetworkReachabilityGetFlags(reachabilityRef, &flags);
-
- return [NSString stringWithFormat: @"%@\n\t%@", self.key, reachabilityFlags_(flags)];
-
- } // description
- #endif
- #pragma mark -
- #pragma mark Notification Management Methods
- //Start listening for reachability notifications on the current run loop
- static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info) {
- #pragma unused (target, flags)
- NSCAssert(info, @"info was NULL in ReachabilityCallback");
- NSCAssert([(NSObject*) info isKindOfClass: [Reachability class]], @"info was the wrong class in ReachabilityCallback");
-
- //We're on the main RunLoop, so an NSAutoreleasePool is not necessary, but is added defensively
- // in case someone uses the Reachablity object in a different thread.
- NSAutoreleasePool* pool = [NSAutoreleasePool new];
-
- // Post a notification to notify the client that the network reachability changed.
- [[NSNotificationCenter defaultCenter] postNotificationName: kReachabilityChangedNotification
- object: (Reachability *) info];
-
- [pool release];
- } // ReachabilityCallback()
- - (BOOL) startNotifier {
-
- SCNetworkReachabilityContext context = {0, self, NULL, NULL, NULL};
-
- if(SCNetworkReachabilitySetCallback(reachabilityRef, ReachabilityCallback, &context)) {
-
- if(SCNetworkReachabilityScheduleWithRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode)) {
- return YES;
-
- }
-
- }
-
- return NO;
- } // startNotifier
- - (void) stopNotifier {
-
- if(reachabilityRef) {
-
- SCNetworkReachabilityUnscheduleFromRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
- }
- } // stopNotifier
- - (BOOL) isEqual: (Reachability *) r {
-
- return [r.key isEqualToString: self.key];
-
- } // isEqual:
- #pragma mark -
- #pragma mark Reachability Allocation Methods
- + (Reachability *) reachabilityWithHostName: (NSString *) hostName {
-
- SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]);
-
- if (ref) {
-
- Reachability *r = [[[self alloc] initWithReachabilityRef: ref] autorelease];
-
- r.key = hostName;
- return r;
-
- }
-
- return nil;
-
- } // reachabilityWithHostName
- + (NSString *) makeAddressKey: (in_addr_t) addr {
- // addr is assumed to be in network byte order.
-
- static const int highShift = 24;
- static const int highMidShift = 16;
- static const int lowMidShift = 8;
- static const in_addr_t mask = 0x000000ff;
-
- addr = ntohl(addr);
-
- return [NSString stringWithFormat: @"%d.%d.%d.%d",
- (addr >> highShift) & mask,
- (addr >> highMidShift) & mask,
- (addr >> lowMidShift) & mask,
- addr & mask];
-
- } // makeAddressKey:
- + (Reachability *) reachabilityWithAddress: (const struct sockaddr_in *) hostAddress {
-
- SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress);
- if (ref) {
-
- Reachability *r = [[[self alloc] initWithReachabilityRef: ref] autorelease];
-
- r.key = [self makeAddressKey: hostAddress->sin_addr.s_addr];
-
- return r;
-
- }
-
- return nil;
- } // reachabilityWithAddress
- + (Reachability *) reachabilityForInternetConnection {
-
- struct sockaddr_in zeroAddress;
- bzero(&zeroAddress, sizeof(zeroAddress));
- zeroAddress.sin_len = sizeof(zeroAddress);
- zeroAddress.sin_family = AF_INET;
- Reachability *r = [self reachabilityWithAddress: &zeroAddress];
- r.key = kInternetConnection;
-
- return r;
- } // reachabilityForInternetConnection
- + (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 *r = [self reachabilityWithAddress: &localWifiAddress];
- r.key = kLocalWiFiConnection;
- return r;
- } // reachabilityForLocalWiFi
- #pragma mark -
- #pragma mark Network Flag Handling Methods
- #if USE_DDG_EXTENSIONS
- //
- // iPhone condition codes as reported by a 3GS running iPhone OS v3.0.
- // Airplane Mode turned on: Reachability Flag Status: -- -------
- // WWAN Active: Reachability Flag Status: WR -t-----
- // WWAN Connection required: Reachability Flag Status: WR ct-----
- // WiFi turned on: Reachability Flag Status: -R ------- Reachable.
- // Local WiFi turned on: Reachability Flag Status: -R xxxxxxd Reachable.
- // WiFi turned on: Reachability Flag Status: -R ct----- Connection down. (Non-intuitive, empirically determined answer.)
- const SCNetworkReachabilityFlags kConnectionDown = kSCNetworkReachabilityFlagsConnectionRequired |
- kSCNetworkReachabilityFlagsTransientConnection;
- // WiFi turned on: Reachability Flag Status: -R ct-i--- Reachable but it will require user intervention (e.g. enter a WiFi password).
- // WiFi turned on: Reachability Flag Status: -R -t----- Reachable via VPN.
- //
- // In the below method, an 'x' in the flag status means I don't care about its value.
- //
- // This method differs from Apple's by testing explicitly for empirically observed values.
- // This gives me more confidence in it's correct behavior. Apple's code covers more cases
- // than mine. My code covers the cases that occur.
- //
- - (NetworkStatus) networkStatusForFlags: (SCNetworkReachabilityFlags) flags {
-
- if (flags & kSCNetworkReachabilityFlagsReachable) {
-
- // Local WiFi -- Test derived from Apple's code: -localWiFiStatusForFlags:.
- if (self.key == kLocalWiFiConnection) {
- // Reachability Flag Status: xR xxxxxxd Reachable.
- return (flags & kSCNetworkReachabilityFlagsIsDirect) ? kReachableViaWiFi : kNotReachable;
- }
-
- // Observed WWAN Values:
- // WWAN Active: Reachability Flag Status: WR -t-----
- // WWAN Connection required: Reachability Flag Status: WR ct-----
- //
- // Test Value: Reachability Flag Status: WR xxxxxxx
- if (flags & kSCNetworkReachabilityFlagsIsWWAN) { return kReachableViaWWAN; }
-
- // Clear moot bits.
- flags &= ~kSCNetworkReachabilityFlagsReachable;
- flags &= ~kSCNetworkReachabilityFlagsIsDirect;
- flags &= ~kSCNetworkReachabilityFlagsIsLocalAddress; // kInternetConnection is local.
-
- // Reachability Flag Status: -R ct---xx Connection down.
- if (flags == kConnectionDown) { return kNotReachable; }
-
- // Reachability Flag Status: -R -t---xx Reachable. WiFi + VPN(is up) (Thank you Ling Wang)
- if (flags & kSCNetworkReachabilityFlagsTransientConnection) { return kReachableViaWiFi; }
-
- // Reachability Flag Status: -R -----xx Reachable.
- if (flags == 0) { return kReachableViaWiFi; }
-
- // Apple's code tests for dynamic connection types here. I don't.
- // If a connection is required, regardless of whether it is on demand or not, it is a WiFi connection.
- // If you care whether a connection needs to be brought up, use -isConnectionRequired.
- // If you care about whether user intervention is necessary, use -isInterventionRequired.
- // If you care about dynamically establishing the connection, use -isConnectionIsOnDemand.
- // Reachability Flag Status: -R cxxxxxx Reachable.
- if (flags & kSCNetworkReachabilityFlagsConnectionRequired) { return kReachableViaWiFi; }
-
- // Required by the compiler. Should never get here. Default to not connected.
- #if (defined DEBUG && defined CLASS_DEBUG)
- NSAssert1(NO, @"Uncaught reachability test. Flags: %@", reachabilityFlags_(flags));
- #endif
- return kNotReachable;
- }
-
- // Reachability Flag Status: x- xxxxxxx
- return kNotReachable;
-
- } // networkStatusForFlags:
- - (NetworkStatus) currentReachabilityStatus {
-
- NSAssert(reachabilityRef, @"currentReachabilityStatus called with NULL reachabilityRef");
-
- SCNetworkReachabilityFlags flags = 0;
- NetworkStatus status = kNotReachable;
-
- if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
-
- // logReachabilityFlags(flags);
-
- status = [self networkStatusForFlags: flags];
-
- return status;
-
- }
-
- return kNotReachable;
-
- } // currentReachabilityStatus
- - (BOOL) isReachable {
-
- NSAssert(reachabilityRef, @"isReachable called with NULL reachabilityRef");
-
- SCNetworkReachabilityFlags flags = 0;
- NetworkStatus status = kNotReachable;
-
- if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
-
- // logReachabilityFlags(flags);
- status = [self networkStatusForFlags: flags];
- // logNetworkStatus(status);
-
- return (kNotReachable != status);
-
- }
-
- return NO;
-
- } // isReachable
- - (BOOL) isConnectionRequired {
-
- NSAssert(reachabilityRef, @"isConnectionRequired called with NULL reachabilityRef");
-
- SCNetworkReachabilityFlags flags;
-
- if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
-
- logReachabilityFlags(flags);
-
- return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
- }
-
- return NO;
-
- } // isConnectionRequired
- - (BOOL) connectionRequired {
-
- return [self isConnectionRequired];
-
- } // connectionRequired
- #endif
- #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 30000)
- static const SCNetworkReachabilityFlags kOnDemandConnection = kSCNetworkReachabilityFlagsConnectionOnTraffic |
- kSCNetworkReachabilityFlagsConnectionOnDemand;
- #else
- static const SCNetworkReachabilityFlags kOnDemandConnection = kSCNetworkReachabilityFlagsConnectionAutomatic;
- #endif
- - (BOOL) isConnectionOnDemand {
-
- NSAssert(reachabilityRef, @"isConnectionIsOnDemand called with NULL reachabilityRef");
-
- SCNetworkReachabilityFlags flags;
-
- if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
-
- logReachabilityFlags(flags);
-
- return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) &&
- (flags & kOnDemandConnection));
-
- }
-
- return NO;
-
- } // isConnectionOnDemand
- - (BOOL) isInterventionRequired {
-
- NSAssert(reachabilityRef, @"isInterventionRequired called with NULL reachabilityRef");
-
- SCNetworkReachabilityFlags flags;
-
- if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
-
- logReachabilityFlags(flags);
-
- return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) &&
- (flags & kSCNetworkReachabilityFlagsInterventionRequired));
-
- }
-
- return NO;
-
- } // isInterventionRequired
- - (BOOL) isReachableViaWWAN {
-
- NSAssert(reachabilityRef, @"isReachableViaWWAN called with NULL reachabilityRef");
-
- SCNetworkReachabilityFlags flags = 0;
- NetworkStatus status = kNotReachable;
-
- if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
-
- logReachabilityFlags(flags);
-
- status = [self networkStatusForFlags: flags];
-
- return (kReachableViaWWAN == status);
-
- }
-
- return NO;
-
- } // isReachableViaWWAN
- - (BOOL) isReachableViaWiFi {
-
- NSAssert(reachabilityRef, @"isReachableViaWiFi called with NULL reachabilityRef");
-
- SCNetworkReachabilityFlags flags = 0;
- NetworkStatus status = kNotReachable;
-
- if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
-
- logReachabilityFlags(flags);
-
- status = [self networkStatusForFlags: flags];
-
- return (kReachableViaWiFi == status);
-
- }
-
- return NO;
-
- } // isReachableViaWiFi
- - (SCNetworkReachabilityFlags) reachabilityFlags {
-
- NSAssert(reachabilityRef, @"reachabilityFlags called with NULL reachabilityRef");
-
- SCNetworkReachabilityFlags flags = 0;
-
- if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
-
- logReachabilityFlags(flags);
-
- return flags;
-
- }
-
- return 0;
-
- } // reachabilityFlags
- #pragma mark -
- #pragma mark Apple's Network Flag Handling Methods
- #if !USE_DDG_EXTENSIONS
- /*
- *
- * Apple's Network Status testing code.
- * The only changes that have been made are to use the new logReachabilityFlags macro and
- * test for local WiFi via the key instead of Apple's boolean. Also, Apple's code was for v3.0 only
- * iPhone OS. v2.2.1 and earlier conditional compiling is turned on. Hence, to mirror Apple's behavior,
- * set your Base SDK to v3.0 or higher.
- *
- */
- - (NetworkStatus) localWiFiStatusForFlags: (SCNetworkReachabilityFlags) flags
- {
- logReachabilityFlags(flags);
-
- BOOL retVal = NotReachable;
- if((flags & kSCNetworkReachabilityFlagsReachable) && (flags & kSCNetworkReachabilityFlagsIsDirect))
- {
- retVal = ReachableViaWiFi;
- }
- return retVal;
- }
- - (NetworkStatus) networkStatusForFlags: (SCNetworkReachabilityFlags) flags
- {
- logReachabilityFlags(flags);
- if (!(flags & kSCNetworkReachabilityFlagsReachable))
- {
- // if target host is not reachable
- return NotReachable;
- }
-
- BOOL retVal = NotReachable;
-
- if (!(flags & kSCNetworkReachabilityFlagsConnectionRequired))
- {
- // if target host is reachable and no connection is required
- // then we'll assume (for now) that your on Wi-Fi
- retVal = ReachableViaWiFi;
- }
-
- #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 30000) // Apple advises you to use the magic number instead of a symbol.
- if ((flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ||
- (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic))
- #else
- if (flags & kSCNetworkReachabilityFlagsConnectionAutomatic)
- #endif
- {
- // ... and the connection is on-demand (or on-traffic) if the
- // calling application is using the CFSocketStream or higher APIs
-
- if (!(flags & kSCNetworkReachabilityFlagsInterventionRequired))
- {
- // ... and no [user] intervention is needed
- retVal = ReachableViaWiFi;
- }
- }
-
- if (flags & kSCNetworkReachabilityFlagsIsWWAN)
- {
- // ... but WWAN connections are OK if the calling application
- // is using the CFNetwork (CFSocketStream?) APIs.
- retVal = ReachableViaWWAN;
- }
- return retVal;
- }
- - (NetworkStatus) currentReachabilityStatus
- {
- NSAssert(reachabilityRef, @"currentReachabilityStatus called with NULL reachabilityRef");
-
- NetworkStatus retVal = NotReachable;
- SCNetworkReachabilityFlags flags;
- if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
- {
- if(self.key == kLocalWiFiConnection)
- {
- retVal = [self localWiFiStatusForFlags: flags];
- }
- else
- {
- retVal = [self networkStatusForFlags: flags];
- }
- }
- return retVal;
- }
- - (BOOL) isReachable {
-
- NSAssert(reachabilityRef, @"isReachable called with NULL reachabilityRef");
-
- SCNetworkReachabilityFlags flags = 0;
- NetworkStatus status = kNotReachable;
-
- if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
-
- logReachabilityFlags(flags);
-
- if(self.key == kLocalWiFiConnection) {
-
- status = [self localWiFiStatusForFlags: flags];
-
- } else {
-
- status = [self networkStatusForFlags: flags];
-
- }
-
- return (kNotReachable != status);
-
- }
-
- return NO;
-
- } // isReachable
- - (BOOL) isConnectionRequired {
-
- return [self connectionRequired];
-
- } // isConnectionRequired
- - (BOOL) connectionRequired {
-
- NSAssert(reachabilityRef, @"connectionRequired called with NULL reachabilityRef");
-
- SCNetworkReachabilityFlags flags;
-
- if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
-
- logReachabilityFlags(flags);
-
- return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
-
- }
-
- return NO;
-
- } // connectionRequired
- #endif
- @end