【问题标题】:Re-run a failed NSURLSessionTask重新运行失败的 NSURLSessionTask
【发布时间】:2014-02-07 00:53:58
【问题描述】:

我想知道是否可以重新运行失败的 NSURLSessionDataTask。这是我遇到此问题的上下文。

我有一个使用 AFNetworking 2.0 处理请求的 Web 服务对象。在我的一种方法中,我得到了这个:

[HTTPSessionManager GET:path parameters:params success:^(NSURLSessionDataTask *task, id responseObject) {

} failure:^(NSURLSessionDataTask *task, NSError *error) {
    //sometimes we fail here due to a 401 and have to re-authenticate.
}];

现在,有时 GET 请求会失败,因为我的后端中用户的身份验证令牌是 .所以我想做的是运行一个重新验证块,看看我们是否可以再次登录。像这样的:

[HTTPSessionManager GET:path parameters:params success:^(NSURLSessionDataTask *task, id responseObject) {

} failure:^(NSURLSessionDataTask *task, NSError *error) {
    if (task.response.statusCode == 401)
       RunReAuthenticationBlockWithSuccess:^(BOOL success) {
           //somehow re-run 'task'
        } failure:^{}
}];

有没有办法重新开始任务?

谢谢!

【问题讨论】:

    标签: ios afnetworking-2 nsurlsession


    【解决方案1】:

    如果有人仍然感兴趣,我最终通过继承 HTTPSessionManager 来实现我的解决方案,如下所示:

    typedef void(^AuthenticationCallback)(NSString *updatedAuthToken, NSError *error);
    typedef void(^AuthenticationBlock)(AuthenticationCallback);
    
    
    @interface MYHTTPSessionManager : AFHTTPSessionManager
    @property (nonatomic, copy) AuthenticationBlock authenticationBlock;
    @end
    
    @implementation MYHTTPSessionManager
    
    
    - (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler {
    
    void (^callback)(NSString *, NSError *) = ^(NSString *tokenString, NSError *error) {
        if (tokenString) {
            //ugh...the request here needs to be re-serialized. Can't think of another way to do this
            NSMutableURLRequest *mutableRequest = [request mutableCopy];
            [mutableRequest addValue:AuthorizationHeaderValueWithTokenString(tokenString) forHTTPHeaderField:@"Authorization"];
            NSURLSessionDataTask *task = [super dataTaskWithRequest:[mutableRequest copy] completionHandler:completionHandler];
            [task resume];
        } else {
            completionHandler(nil, nil, error);
        }
    };
    
    void (^reauthCompletion)(NSURLResponse *, id, NSError *) = ^(NSURLResponse *response, id responseObject, NSError *error){
    
        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
        NSInteger unauthenticated = 401;
        if (httpResponse.statusCode == unauthenticated) {
            if (self.authenticationBlock != NULL) {
                self.authenticationBlock(callback); return;
            }
        }
    
        completionHandler(response, responseObject, error);
    };
    
    return [super dataTaskWithRequest:request completionHandler:reauthCompletion];
    }
    
    @end
    

    【讨论】:

    • 非常有趣。不幸的是,如果您在请求 HTTPBody 中传递令牌,它将不起作用。
    • Martin,请不要在请求正文中传递 HTTP 身份验证数据。真的错了!
    • 非常感谢您的回答,帮助很大!但请注意,您返回的可能不是实际的NSURLSessionDataTask
    • @MertBuran 不幸的是真的
    • @SeanDanzeiser 我开始做类似的事情来解决这个问题:github.com/buranmert/MBTaskContainer 它只有 0.1.x 但也许它可以帮助任何人
    猜你喜欢
    • 1970-01-01
    • 2011-12-05
    • 1970-01-01
    • 2013-05-20
    • 2019-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多