To give some context: I'm trying to implement a global error handler for authentication errors (using token authentication, not basic), which should try to re-authenticate and then repeat the original failed request (see my previous question: AFNetworking: Handle error globally and repeat request)
The current approach is to register an observer for the AFNetworkingOperationDidFinishNotification
which does the re-authentication and (if auth succeeded) repeats the original request:
- (void)operationDidFinish:(NSNotification *)notification
{
AFHTTPRequestOperation *operation = (AFHTTPRequestOperation *)[notification object];
if(![operation isKindOfClass:[AFHTTPRequestOperation class]]) {
return;
}
if(403 == [operation.response statusCode]) {
// try to re-authenticate and repeat the original request
[[UserManager sharedUserManager] authenticateWithCredentials...
success:^{
// repeat original request
// AFHTTPRequestOperation *newOperation = [operation copy]; // copies too much stuff, eg. response (although the docs suggest otherwise)
AFHTTPRequestOperation *newOperation = [[AFHTTPRequestOperation alloc] initWithRequest:operation.request];
// PROBLEM 1: newOperation has no completion blocks. How to use the original success/failure blocks here?
[self enqueueHTTPRequestOperation:newOperation];
}
failure:^(NSError *error) {
// PROBLEM 2: How to invoke failure block of original operation?
}
];
}
}
However, I stumbled upon some issues regarding completion blocks of request operations:
When repeating the original request, I obviously want its completion blocks to be executed. However,
AFHTTPRequestOperation
does not retain references to the passed success and failure blocks (seesetCompletionBlockWithSuccess:failure:
) and copyingNSOperation
'scompletionBlock
is probably not a good idea, as the documentation forAFURLConnectionOperation
states:Operation copies do not include
completionBlock
.completionBlock
often strongly captures a reference toself
, which, perhaps surprisingly, would otherwise point to the original operation when copied.In case the re-authentication fails, I want to call the original request's failure block. So, again, I'd need direct access to this.
Am I missing something here? Any ideas for alternative approaches? Should I file a feature request?