diff options
Diffstat (limited to 'platform/ios/test/OHHTTPStubs/OHHTTPStubs/Pods/AFNetworking/AFNetworking/AFNetworkReachabilityManager.m')
-rw-r--r-- | platform/ios/test/OHHTTPStubs/OHHTTPStubs/Pods/AFNetworking/AFNetworking/AFNetworkReachabilityManager.m | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/platform/ios/test/OHHTTPStubs/OHHTTPStubs/Pods/AFNetworking/AFNetworking/AFNetworkReachabilityManager.m b/platform/ios/test/OHHTTPStubs/OHHTTPStubs/Pods/AFNetworking/AFNetworking/AFNetworkReachabilityManager.m new file mode 100644 index 0000000000..1da148282d --- /dev/null +++ b/platform/ios/test/OHHTTPStubs/OHHTTPStubs/Pods/AFNetworking/AFNetworking/AFNetworkReachabilityManager.m @@ -0,0 +1,259 @@ +// AFNetworkReachabilityManager.m +// +// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "AFNetworkReachabilityManager.h" + +#import <netinet/in.h> +#import <netinet6/in6.h> +#import <arpa/inet.h> +#import <ifaddrs.h> +#import <netdb.h> + +NSString * const AFNetworkingReachabilityDidChangeNotification = @"com.alamofire.networking.reachability.change"; +NSString * const AFNetworkingReachabilityNotificationStatusItem = @"AFNetworkingReachabilityNotificationStatusItem"; + +typedef void (^AFNetworkReachabilityStatusBlock)(AFNetworkReachabilityStatus status); + +typedef NS_ENUM(NSUInteger, AFNetworkReachabilityAssociation) { + AFNetworkReachabilityForAddress = 1, + AFNetworkReachabilityForAddressPair = 2, + AFNetworkReachabilityForName = 3, +}; + +NSString * AFStringFromNetworkReachabilityStatus(AFNetworkReachabilityStatus status) { + switch (status) { + case AFNetworkReachabilityStatusNotReachable: + return NSLocalizedStringFromTable(@"Not Reachable", @"AFNetworking", nil); + case AFNetworkReachabilityStatusReachableViaWWAN: + return NSLocalizedStringFromTable(@"Reachable via WWAN", @"AFNetworking", nil); + case AFNetworkReachabilityStatusReachableViaWiFi: + return NSLocalizedStringFromTable(@"Reachable via WiFi", @"AFNetworking", nil); + case AFNetworkReachabilityStatusUnknown: + default: + return NSLocalizedStringFromTable(@"Unknown", @"AFNetworking", nil); + } +} + +static AFNetworkReachabilityStatus AFNetworkReachabilityStatusForFlags(SCNetworkReachabilityFlags flags) { + BOOL isReachable = ((flags & kSCNetworkReachabilityFlagsReachable) != 0); + BOOL needsConnection = ((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0); + BOOL canConnectionAutomatically = (((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) || ((flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0)); + BOOL canConnectWithoutUserInteraction = (canConnectionAutomatically && (flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0); + BOOL isNetworkReachable = (isReachable && (!needsConnection || canConnectWithoutUserInteraction)); + + AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusUnknown; + if (isNetworkReachable == NO) { + status = AFNetworkReachabilityStatusNotReachable; + } +#if TARGET_OS_IPHONE + else if ((flags & kSCNetworkReachabilityFlagsIsWWAN) != 0) { + status = AFNetworkReachabilityStatusReachableViaWWAN; + } +#endif + else { + status = AFNetworkReachabilityStatusReachableViaWiFi; + } + + return status; +} + +static void AFNetworkReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNetworkReachabilityFlags flags, void *info) { + AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusForFlags(flags); + AFNetworkReachabilityStatusBlock block = (__bridge AFNetworkReachabilityStatusBlock)info; + if (block) { + block(status); + } + + + dispatch_async(dispatch_get_main_queue(), ^{ + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + [notificationCenter postNotificationName:AFNetworkingReachabilityDidChangeNotification object:nil userInfo:@{ AFNetworkingReachabilityNotificationStatusItem: @(status) }]; + }); + +} + +static const void * AFNetworkReachabilityRetainCallback(const void *info) { + return Block_copy(info); +} + +static void AFNetworkReachabilityReleaseCallback(const void *info) { + if (info) { + Block_release(info); + } +} + +@interface AFNetworkReachabilityManager () +@property (readwrite, nonatomic, assign) SCNetworkReachabilityRef networkReachability; +@property (readwrite, nonatomic, assign) AFNetworkReachabilityAssociation networkReachabilityAssociation; +@property (readwrite, nonatomic, assign) AFNetworkReachabilityStatus networkReachabilityStatus; +@property (readwrite, nonatomic, copy) AFNetworkReachabilityStatusBlock networkReachabilityStatusBlock; +@end + +@implementation AFNetworkReachabilityManager + ++ (instancetype)sharedManager { + static AFNetworkReachabilityManager *_sharedManager = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + struct sockaddr_in address; + bzero(&address, sizeof(address)); + address.sin_len = sizeof(address); + address.sin_family = AF_INET; + + _sharedManager = [self managerForAddress:&address]; + }); + + return _sharedManager; +} + ++ (instancetype)managerForDomain:(NSString *)domain { + SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [domain UTF8String]); + + AFNetworkReachabilityManager *manager = [[self alloc] initWithReachability:reachability]; + manager.networkReachabilityAssociation = AFNetworkReachabilityForName; + + return manager; +} + ++ (instancetype)managerForAddress:(const void *)address { + SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)address); + + AFNetworkReachabilityManager *manager = [[self alloc] initWithReachability:reachability]; + manager.networkReachabilityAssociation = AFNetworkReachabilityForAddress; + + return manager; +} + +- (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability { + self = [super init]; + if (!self) { + return nil; + } + + self.networkReachability = reachability; + self.networkReachabilityStatus = AFNetworkReachabilityStatusUnknown; + + return self; +} + +- (void)dealloc { + [self stopMonitoring]; + + if (_networkReachability) { + CFRelease(_networkReachability); + _networkReachability = NULL; + } +} + +#pragma mark - + +- (BOOL)isReachable { + return [self isReachableViaWWAN] || [self isReachableViaWiFi]; +} + +- (BOOL)isReachableViaWWAN { + return self.networkReachabilityStatus == AFNetworkReachabilityStatusReachableViaWWAN; +} + +- (BOOL)isReachableViaWiFi { + return self.networkReachabilityStatus == AFNetworkReachabilityStatusReachableViaWiFi; +} + +#pragma mark - + +- (void)startMonitoring { + [self stopMonitoring]; + + if (!self.networkReachability) { + return; + } + + __weak __typeof(self)weakSelf = self; + AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) { + __strong __typeof(weakSelf)strongSelf = weakSelf; + + strongSelf.networkReachabilityStatus = status; + if (strongSelf.networkReachabilityStatusBlock) { + strongSelf.networkReachabilityStatusBlock(status); + } + + }; + + SCNetworkReachabilityContext context = {0, (__bridge void *)callback, AFNetworkReachabilityRetainCallback, AFNetworkReachabilityReleaseCallback, NULL}; + SCNetworkReachabilitySetCallback(self.networkReachability, AFNetworkReachabilityCallback, &context); + SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes); + + switch (self.networkReachabilityAssociation) { + case AFNetworkReachabilityForName: + break; + case AFNetworkReachabilityForAddress: + case AFNetworkReachabilityForAddressPair: + default: { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^{ + SCNetworkReachabilityFlags flags; + SCNetworkReachabilityGetFlags(self.networkReachability, &flags); + AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusForFlags(flags); + dispatch_async(dispatch_get_main_queue(), ^{ + callback(status); + + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + [notificationCenter postNotificationName:AFNetworkingReachabilityDidChangeNotification object:nil userInfo:@{ AFNetworkingReachabilityNotificationStatusItem: @(status) }]; + + + }); + }); + } + break; + } +} + +- (void)stopMonitoring { + if (!self.networkReachability) { + return; + } + + SCNetworkReachabilityUnscheduleFromRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes); +} + +#pragma mark - + +- (NSString *)localizedNetworkReachabilityStatusString { + return AFStringFromNetworkReachabilityStatus(self.networkReachabilityStatus); +} + +#pragma mark - + +- (void)setReachabilityStatusChangeBlock:(void (^)(AFNetworkReachabilityStatus status))block { + self.networkReachabilityStatusBlock = block; +} + +#pragma mark - NSKeyValueObserving + ++ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key { + if ([key isEqualToString:@"reachable"] || [key isEqualToString:@"reachableViaWWAN"] || [key isEqualToString:@"reachableViaWiFi"]) { + return [NSSet setWithObject:@"networkReachabilityStatus"]; + } + + return [super keyPathsForValuesAffectingValueForKey:key]; +} + +@end |