【问题标题】:Retry a HTTP request in iOS在 iOS 中重试 HTTP 请求
【发布时间】:2015-11-04 05:13:03
【问题描述】:

我正在使用 NSURLConnection 发送一个 HTTP 请求并运行它 [[NSURLConnection alloc] initWithRequest:request delegate:self]; 其中“request”是一个配置好的 NSMutableURLRequest 对象。基于错误代码(404 或 500)的 HTTP 错误,我想重试请求。

我在“connection: didReceiveResponse”委托方法中得到错误响应和 HTTP 状态代码。我应该如何实现重试请求?

提前致谢!

P.S:我尝试取消连接并在收到错误时启动它,但它没有效果,因为 NSURLConnection 在完成加载或取消后释放委托。

-----更新-----

    -(void)doHTTPGet:(NSString *)url delegate:(id  <NSURLConnectionDelegate>)delegate timeout:(NSTimeInterval)timeout
{
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]
                                                           cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                       timeoutInterval:timeout];
    [request setHTTPMethod:@"GET"];
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];

    // send request by instanciating NSURLConnection
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:delegate];

}

在我的模型类中,我有调用者方法和委托

来电者:

[MyModel doHTTPGet:url delegate:self timeout:HTTP_TIMEOUT];

委托方法:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
    httpResponseStatusCode = [httpResponse statusCode];
    DLOG(@"HTTP status code=%ld", (long)httpResponseStatusCode);

    if (httpResponseStatusCode == 404)
    {
       // RETRY HERE
    } 
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [httpResponseData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{

    // some code PROCESSING RESPONSE
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
        }

【问题讨论】:

    标签: ios objective-c asynchronous nsurlconnection


    【解决方案1】:

    我将NSURLConnection 功能的东西包装在另一个类(在我的例子中,称为 APIGetter)中,它有自己的委托协议和方法并处理重试等事情。

    如果您不想这样做,则需要保存参数和 URL,然后再试一次,可能在 connectionDidFinishLoading: 中。

    不过,我试图想象一个场景,您希望重试 4xx HTTP 错误。似乎更有可能出现连接错误,因此您将其放入connection:didFailWithError

    【讨论】:

    • 我最初在 connectionDidFinishLoading if(httpResponseStatusCode == 404) { [MyModel doGet:[connection currentRequest].URL delegate:self timeout:HTTP_TIMEOUT ]; }
    • 但是由于重试请求是异步的,所以当我得到响应时,下一部分代码正在执行..
    • 收到回复时?仅当您准备好时,您才应该调用您的其他代码。
    • 我其实是想重试500错误,委托方法-connection:didFailWithError不会在4XX或5XX错误时触发
    • 是的,知道了。我的错,我在那里有一个不正确的条件,因为下一个回调代码在没有等待 HTTP 操作的情况下触发。我现在可以正常工作了..谢谢
    【解决方案2】:

    在您的响应中,只需使用 switch 或 if 语句来检查您希望的错误,如果您的响应是 404 或 500,请重新加载请求

    这是伪代码:

    如果错误包含字符串(404 或 500){

    //调用加载请求的函数

    }

    【讨论】:

    • 我最初在 connectionDidFinishLoading if(httpResponseStatusCode == 404) { [MyModel doGet:[connection currentRequest].URL delegate:self timeout:HTTP_TIMEOUT ]; }
    • 但是由于重试请求是异步的,所以当我得到响应时,下一部分代码正在执行中..
    • 你试过了吗 //Capturing server response NSData* result = [NSURLConnection sendSynchronousRequest:request returnedResponse:&response error:&error];
    • 我需要使用异步请求重试,因为我需要处理响应。我无法发送同步请求
    【解决方案3】:

    我会为您推荐STNetTaskQueue,因为它为每个网络任务提供重试时间和重试间隔。

    此外,它可以自动从请求对象中打包请求参数,并且最大并发网络任务也是可配置的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-05
      • 1970-01-01
      • 2011-07-14
      • 2021-10-08
      相关资源
      最近更新 更多