diff --git a/AFNetworking/AFHTTPClient.h b/AFNetworking/AFHTTPClient.h index 6797d4f..8b713cb 100644 --- a/AFNetworking/AFHTTPClient.h +++ b/AFNetworking/AFHTTPClient.h @@ -27,7 +27,18 @@ @protocol AFMultipartFormData; /** - Method used to encode parameters into request body + Posted when network reachability changes. + The notification object is an `NSNumber` object containing the boolean value for the current network reachability. + This notification contains no information in the `userInfo` dictionary. + + @warning In order for network reachability to be monitored, include the `SystemConfiguration` framework in the active target's "Link Binary With Library" build phase, and add `#import ` to the header prefix of the project (Prefix.pch). + */ +#ifdef _SYSTEMCONFIGURATION_H +extern NSString * const AFNetworkingReachabilityDidChangeNotification; +#endif + +/** + Method used to encode parameters into request body. */ typedef enum { AFFormURLParameterEncoding, diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index cb3905e..5ff7343 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -36,6 +36,8 @@ #import #endif +NSString * const AFNetworkingReachabilityDidChangeNotification = @"com.alamofire.networking.reachability.change"; + static NSString * const kAFMultipartFormLineDelimiter = @"\r\n"; // CRLF static NSString * const kAFMultipartFormBoundary = @"Boundary+0xAbCdEfGbOuNdArY"; @@ -148,6 +150,11 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) { @property (readwrite, nonatomic, retain) NSOperationQueue *operationQueue; @property (readwrite, nonatomic, assign) AFNetworkReachabilityRef networkReachability; @property (readwrite, nonatomic, copy) AFNetworkReachabilityStatusBlock networkReachabilityStatusBlock; + +#ifdef _SYSTEMCONFIGURATION_H +- (void)startMonitoringNetworkReachability; +- (void)stopMonitoringNetworkReachability; +#endif @end @implementation AFHTTPClient @@ -193,6 +200,10 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) { [self setDefaultHeader:@"User-Agent" value:[NSString stringWithFormat:@"%@/%@ (%@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey], @"unknown"]]; #endif +#ifdef _SYSTEMCONFIGURATION_H + [self startMonitoringNetworkReachability]; +#endif + self.operationQueue = [[[NSOperationQueue alloc] init] autorelease]; [self.operationQueue setMaxConcurrentOperationCount:kAFHTTPClientDefaultMaxConcurrentOperationCount]; @@ -200,14 +211,15 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) { } - (void)dealloc { +#ifdef _SYSTEMCONFIGURATION_H + [self stopMonitoringNetworkReachability]; +#endif + [_baseURL release]; [_registeredHTTPOperationClassNames release]; [_defaultHeaders release]; [_operationQueue release]; [_networkReachabilityStatusBlock release]; - if (_networkReachability) { - CFRelease(_networkReachability); - } [super dealloc]; } @@ -220,29 +232,37 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) { #ifdef _SYSTEMCONFIGURATION_H static void AFReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNetworkReachabilityFlags flags, void *info) { - if (info) { - AFNetworkReachabilityStatusBlock block = (AFNetworkReachabilityStatusBlock)info; - - BOOL isReachable = ((flags & kSCNetworkReachabilityFlagsReachable) != 0); - BOOL needsConnection = ((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0); - BOOL isNetworkReachable = (isReachable && !needsConnection); + BOOL isReachable = ((flags & kSCNetworkReachabilityFlagsReachable) != 0); + BOOL needsConnection = ((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0); + BOOL isNetworkReachable = (isReachable && !needsConnection); + AFNetworkReachabilityStatusBlock block = (AFNetworkReachabilityStatusBlock)info; + if (block) { block(isNetworkReachable); } + + [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingReachabilityDidChangeNotification object:[NSNumber numberWithBool:isNetworkReachable]]; } -- (void)setReachabilityStatusChangeBlock:(void (^)(BOOL isNetworkReachable))block { - if (_networkReachability) { - SCNetworkReachabilityUnscheduleFromRunLoop(_networkReachability, CFRunLoopGetMain(), (CFStringRef)NSRunLoopCommonModes); - CFRelease(_networkReachability); - } - - self.networkReachabilityStatusBlock = block; +- (void)startMonitoringNetworkReachability { + [self stopMonitoringNetworkReachability]; self.networkReachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [[self.baseURL host] UTF8String]); SCNetworkReachabilityContext context = {0, self.networkReachabilityStatusBlock, NULL, NULL, NULL}; SCNetworkReachabilitySetCallback(self.networkReachability, AFReachabilityCallback, &context); SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), (CFStringRef)NSRunLoopCommonModes); } + +- (void)stopMonitoringNetworkReachability { + if (_networkReachability) { + SCNetworkReachabilityUnscheduleFromRunLoop(_networkReachability, CFRunLoopGetMain(), (CFStringRef)NSRunLoopCommonModes); + CFRelease(_networkReachability); + } +} + +- (void)setReachabilityStatusChangeBlock:(void (^)(BOOL isNetworkReachable))block { + self.networkReachabilityStatusBlock = block; + [self startMonitoringNetworkReachability]; +} #endif #pragma mark -