Adding notifications for network reachability changes to AFHTTPClient

This commit is contained in:
Mattt Thompson 2012-02-01 11:27:57 -08:00
parent 37559c792c
commit 4266dc60d1
2 changed files with 48 additions and 17 deletions

View file

@ -27,7 +27,18 @@
@protocol AFMultipartFormData; @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 <SystemConfiguration/SystemConfiguration.h>` 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 { typedef enum {
AFFormURLParameterEncoding, AFFormURLParameterEncoding,

View file

@ -36,6 +36,8 @@
#import <SystemConfiguration/SystemConfiguration.h> #import <SystemConfiguration/SystemConfiguration.h>
#endif #endif
NSString * const AFNetworkingReachabilityDidChangeNotification = @"com.alamofire.networking.reachability.change";
static NSString * const kAFMultipartFormLineDelimiter = @"\r\n"; // CRLF static NSString * const kAFMultipartFormLineDelimiter = @"\r\n"; // CRLF
static NSString * const kAFMultipartFormBoundary = @"Boundary+0xAbCdEfGbOuNdArY"; static NSString * const kAFMultipartFormBoundary = @"Boundary+0xAbCdEfGbOuNdArY";
@ -148,6 +150,11 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) {
@property (readwrite, nonatomic, retain) NSOperationQueue *operationQueue; @property (readwrite, nonatomic, retain) NSOperationQueue *operationQueue;
@property (readwrite, nonatomic, assign) AFNetworkReachabilityRef networkReachability; @property (readwrite, nonatomic, assign) AFNetworkReachabilityRef networkReachability;
@property (readwrite, nonatomic, copy) AFNetworkReachabilityStatusBlock networkReachabilityStatusBlock; @property (readwrite, nonatomic, copy) AFNetworkReachabilityStatusBlock networkReachabilityStatusBlock;
#ifdef _SYSTEMCONFIGURATION_H
- (void)startMonitoringNetworkReachability;
- (void)stopMonitoringNetworkReachability;
#endif
@end @end
@implementation AFHTTPClient @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"]]; [self setDefaultHeader:@"User-Agent" value:[NSString stringWithFormat:@"%@/%@ (%@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey], @"unknown"]];
#endif #endif
#ifdef _SYSTEMCONFIGURATION_H
[self startMonitoringNetworkReachability];
#endif
self.operationQueue = [[[NSOperationQueue alloc] init] autorelease]; self.operationQueue = [[[NSOperationQueue alloc] init] autorelease];
[self.operationQueue setMaxConcurrentOperationCount:kAFHTTPClientDefaultMaxConcurrentOperationCount]; [self.operationQueue setMaxConcurrentOperationCount:kAFHTTPClientDefaultMaxConcurrentOperationCount];
@ -200,14 +211,15 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) {
} }
- (void)dealloc { - (void)dealloc {
#ifdef _SYSTEMCONFIGURATION_H
[self stopMonitoringNetworkReachability];
#endif
[_baseURL release]; [_baseURL release];
[_registeredHTTPOperationClassNames release]; [_registeredHTTPOperationClassNames release];
[_defaultHeaders release]; [_defaultHeaders release];
[_operationQueue release]; [_operationQueue release];
[_networkReachabilityStatusBlock release]; [_networkReachabilityStatusBlock release];
if (_networkReachability) {
CFRelease(_networkReachability);
}
[super dealloc]; [super dealloc];
} }
@ -220,29 +232,37 @@ static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) {
#ifdef _SYSTEMCONFIGURATION_H #ifdef _SYSTEMCONFIGURATION_H
static void AFReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNetworkReachabilityFlags flags, void *info) { static void AFReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNetworkReachabilityFlags flags, void *info) {
if (info) { BOOL isReachable = ((flags & kSCNetworkReachabilityFlagsReachable) != 0);
AFNetworkReachabilityStatusBlock block = (AFNetworkReachabilityStatusBlock)info; 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); block(isNetworkReachable);
} }
[[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingReachabilityDidChangeNotification object:[NSNumber numberWithBool:isNetworkReachable]];
} }
- (void)setReachabilityStatusChangeBlock:(void (^)(BOOL isNetworkReachable))block { - (void)startMonitoringNetworkReachability {
if (_networkReachability) { [self stopMonitoringNetworkReachability];
SCNetworkReachabilityUnscheduleFromRunLoop(_networkReachability, CFRunLoopGetMain(), (CFStringRef)NSRunLoopCommonModes);
CFRelease(_networkReachability);
}
self.networkReachabilityStatusBlock = block;
self.networkReachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [[self.baseURL host] UTF8String]); self.networkReachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [[self.baseURL host] UTF8String]);
SCNetworkReachabilityContext context = {0, self.networkReachabilityStatusBlock, NULL, NULL, NULL}; SCNetworkReachabilityContext context = {0, self.networkReachabilityStatusBlock, NULL, NULL, NULL};
SCNetworkReachabilitySetCallback(self.networkReachability, AFReachabilityCallback, &context); SCNetworkReachabilitySetCallback(self.networkReachability, AFReachabilityCallback, &context);
SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), (CFStringRef)NSRunLoopCommonModes); 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 #endif
#pragma mark - #pragma mark -