重新运行失败的 NSURLSessionTask

Posted

技术标签:

【中文标题】重新运行失败的 NSURLSessionTask【英文标题】:Re-run a failed 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:^
];

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

谢谢!

【问题讨论】:

【参考方案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 但也许它可以帮助任何人

以上是关于重新运行失败的 NSURLSessionTask的主要内容,如果未能解决你的问题,请参考以下文章

iOS SDWebImage 加载网络图片失败,重新运行才有图片

执行用例失败后重新运行

在黄瓜 java+testng 中自动重新运行失败的唯一场景

如何在 Espresso 中重新运行失败的测试? - 头脑风暴

如何在 Airflow 上重新启动失败的任务

Maven Surefire 插件没有重新运行失败的 Cucumber 测试