提供一些上下文:我正在尝试为身份验证错误(使用令牌身份验证,而不是基本身份)实现全局错误处理程序,这应该尝试重新进行身份验证,然后重复原始失败的请求(请参阅我之前的问题: AFNetworking: Handle error globally and repeat request)
当前的方法是注册AFNetworkingOperationDidFinishNotification
的观察者进行重新认证,并且(如果auth成功)重复原始请求:
- (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?
}
];
}
}
但是,我偶然发现了有关请求操作完成块的一些问题:
重复原始请求时,我显然希望执行完成块。但是,AFHTTPRequestOperation
不会保留对已通过的成功和失败块的引用(请参阅setCompletionBlockWithSuccess:failure:
),而复制NSOperation
的{{1}}可能不是一个好主意,因为文档对于completionBlock
州:
操作副本不包括
AFURLConnectionOperation
。completionBlock
通常会强烈捕获对completionBlock
的引用,这可能会令人惊讶地在复制时指向原始操作。
如果重新验证失败,我想调用原始请求的失败块。所以,再一次,我需要直接访问它。
我在这里遗漏了什么吗?任何替代方法的想法?我应该提交功能请求吗?
答案 0 :(得分:1)
我在Art.sy的投资组合应用程序中提出了这个问题。我最终的结论是创建了一个NSOperationQueue子类,它具有在失败后创建各种AFNetworking HTTP操作的副本的功能(并且在放弃之前每个URL最多执行三次。)
答案 1 :(得分:0)
您是否尝试过以下操作?
// set success / failure block of original operation
[newOperation setCompletionBlock:[operation.completionBlock copy]];
[operation setCompletionBlock:nil];
请注意,如果在原始完成/失败块中捕获self(即访问任何ivars),则在执行newOperation的完成块时实际访问原始操作实例。但这实际上是你想要的,对吗?
通知处理程序在操作的完成块之前执行。 因此,您应该将原始操作的完成块设置为nil,以防止它执行两次。
请注意,完成块在执行后设置为nil(参见AFURLConnectionOperation)。
在authenticateWithCredentials失败块中,您不应该做任何事情。原来的操作已经完成,并且已经执行了它的故障块。