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;
/**
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 {
AFFormURLParameterEncoding,

View file

@ -36,6 +36,8 @@
#import <SystemConfiguration/SystemConfiguration.h>
#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);
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 -