After reading this stackoverflow post, I thought that I would simplify it by subclassing AFHTTPRequestOperationManager
and wrap all of this stuff in a new method that I called GET:parameters:success:failure:unmodified
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
@interface CSTHTTPRequestOperationManager : AFHTTPRequestOperationManager - (AFHTTPRequestOperation *)GET:(NSString *)URLString parameters:(NSDictionary *)parameters success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure unmodified:(void (^)(AFHTTPRequestOperation *operation, id responseObject))unmodified; @end @implementation CSTHTTPRequestOperationManager +(void)initialize { if ( self == [CSTHTTPRequestOperationManager class] ) { [NSURLCache sharedURLCache]; } } - (AFHTTPRequestOperation *)GET:(NSString *)URLString parameters:(NSDictionary *)parameters success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure unmodified:(void (^)(AFHTTPRequestOperation *operation, id responseObject))unmodified { BOOL __block responseFromCache = YES; void (^successWrapper)(AFHTTPRequestOperation *operation, id responseObject) = ^(AFHTTPRequestOperation *operation, id responseObject) { if (responseFromCache) { unmodified(operation,responseObject); } else { success(operation,responseObject); } }; NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"GET" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:nil]; [request setCachePolicy:NSURLRequestReturnCacheDataElseLoad]; AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:successWrapper failure:failure]; [operation setCacheResponseBlock:^NSCachedURLResponse *(NSURLConnection *connection, NSCachedURLResponse *cachedResponse) { // this will be called whenever server returns status code 200, not 304 responseFromCache = NO; return cachedResponse; }]; [self.operationQueue addOperation:operation]; return operation; } @end |
According to this other stackoverflow post, NSURLCache
needs a little bit of time to warm up, so I added a class initializer. From your AppDelegate’s application:didFinishLaunchingWithOptions:
method you can call this early:
1 |
[CSTHTTPRequestOperationManager class]; |
Using this new method is simple:
1 2 3 4 5 6 7 8 9 |
CSTHTTPRequestOperationManager *manager = [CSTHTTPRequestOperationManager manager]; manager.responseSerializer = [AFXMLParserResponseSerializer new]; [manager GET:URL parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { // HTTP 200 response } failure:^(AFHTTPRequestOperation *operation, NSError *error) { // Neither 200 nor 304 } unmodified:^(AFHTTPRequestOperation *operation, id responseObject) { // HTTP 304 response }]; |
Hopefully this will be useful for you. If you’re worried about a nil unmodified
or success
block, you can prefix those calls with if (unmodified) unmodified(operation,responseObject)
and if (success) success(operation,responseObject)
.