add .gitignore
This commit is contained in:
814
msext/Class/Common/ASIHttpRequest/Reachability.m
Executable file
814
msext/Class/Common/ASIHttpRequest/Reachability.m
Executable file
@@ -0,0 +1,814 @@
|
||||
/*
|
||||
|
||||
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 = @"Not Reachable";
|
||||
break;
|
||||
case kReachableViaWWAN:
|
||||
statusString = @"Reachable via WWAN";
|
||||
break;
|
||||
case kReachableViaWiFi:
|
||||
statusString = @"Reachable via WiFi";
|
||||
break;
|
||||
}
|
||||
|
||||
NSLog(@"%s (%d) \n\tNetwork Status: %@", name, line, statusString);
|
||||
|
||||
} // logNetworkStatus_()
|
||||
|
||||
#else
|
||||
#define logReachabilityFlags(flags)
|
||||
#define logNetworkStatus(status)
|
||||
#endif
|
||||
|
||||
@interface Reachability ()
|
||||
|
||||
- (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
|
||||
Reference in New Issue
Block a user