AFNetworking:全局处理错误并重复请求

Dan*_*ser 37 networking ios afnetworking

我有一个相当常见的用例,但我找不到一个简单的方法来处理AFNetworking:

每当服务器返回任何请求的特定状态代码时,我想:

  • 删除缓存的身份验证令牌
  • 重新认证(这是一个单独的请求)
  • 重复失败的请求.

我认为这可以通过一些全局完成/错误处理程序来完成AFHTTPClient,但我没有找到任何有用的东西.那么,做"我想要的"的"正确"方式是什么?enqueueHTTPRequestOperation:在我的AFHTTPClient子类中重写,复制操作并用一个执行我想要的块(重新验证,排队复制操作)包装原始完成处理程序?或者我完全走错了路?

谢谢!

编辑:删除了对401状态代码的引用,因为当我使用令牌身份验证时,这可能是为HTTP basic保留的.

ada*_*mup 30

我使用AFNetworking 2.0替代方法.

您可以dataTaskWithRequest:success:failure:通过一些错误检查对传递的完成块进行子类化和包装.例如,如果您正在使用OAuth,则可以查看401错误(到期)并刷新您的访问令牌.

- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)urlRequest completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))originalCompletionHandler{

    //create a completion block that wraps the original
    void (^authFailBlock)(NSURLResponse *response, id responseObject, NSError *error) = ^(NSURLResponse *response, id responseObject, NSError *error)
    {
        NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
        if([httpResponse statusCode] == 401){
            NSLog(@"401 auth error!");
            //since there was an error, call you refresh method and then redo the original task
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{

                //call your method for refreshing OAuth tokens.  This is an example:
                [self refreshAccessToken:^(id responseObject) {

                    NSLog(@"response was %@", responseObject);
                    //store your new token

                    //now, queue up and execute the original task               
                    NSURLSessionDataTask *originalTask = [super dataTaskWithRequest:urlRequest completionHandler:originalCompletionHandler];
                    [originalTask resume];
                }];                    
            });
        }else{
            NSLog(@"no auth error");
            originalCompletionHandler(response, responseObject, error);
        }
    };

    NSURLSessionDataTask *task = [super dataTaskWithRequest:urlRequest completionHandler:authFailBlock];

    return task;

}
Run Code Online (Sandbox Code Playgroud)


Fel*_*lix 21

在AFHTTPClient的init方法寄存器中AFNetworkingOperationDidFinishNotification,将在请求完成后发布.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(HTTPOperationDidFinish:) name:AFNetworkingOperationDidFinishNotification object:nil];
Run Code Online (Sandbox Code Playgroud)

在通知处理程序检查状态码和copyAFHTTPRequestOperation或创建一个新的.

- (void)HTTPOperationDidFinish:(NSNotification *)notification {
  AFHTTPRequestOperation *operation = (AFHTTPRequestOperation *)[notification object];

    if (![operation isKindOfClass:[AFHTTPRequestOperation class]]) {
        return;
    }

    if ([operation.response statusCode] == 401) {
        // enqueue a new request operation here
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:

通常,您不需要这样做,只需使用此AFNetworking方法处理身份验证:

- (void)setAuthenticationChallengeBlock:(void (^)(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge))block;
Run Code Online (Sandbox Code Playgroud)

  • 似乎我对复制操作的乐观态度是错误的:首先,`copy`复制太多东西(例如响应).其次,它不包括原始请求的完成块,这对我来说是一个交易破坏者.请参阅我的后续问题:http://stackoverflow.com/questions/12951037/afnetworking-access-to-completion-handlers-when-retrying-operation (2认同)

归档时间:

查看次数:

15047 次

最近记录:

9 年,9 月 前