Как повторить запрос URL-адреса на основе блоков

Я извлекаю данные с помощью новых методов запроса URL-адресов iOS7, например:

NSMutableURLRequest *request = [NSMutableURLRequest
    requestWithURL:[NSURL URLWithString:[self.baseUrl 
    stringByAppendingString:path]]];

NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
    NSUInteger responseStatusCode = [httpResponse statusCode];

    if (responseStatusCode != 200) { 
        // RETRY (??????) 
    } else       
        completionBlock(results[@"result"][symbol]);
}];
[dataTask resume];

К сожалению, время от времени я получаю HTTP-ответы, указывающие, что сервер недоступен (response code != 200), и ему нужно отправить тот же запрос на сервер.

Как это можно сделать? Как мне нужно заполнить фрагмент кода выше, где мой комментарий // RETRY есть?

В моем примере я вызываю блок завершения после успешной выборки. Но как я могу отправить тот же запрос еще раз?

Спасибо!

Ответ 1

Поместите свой код запроса в метод и вызовите его еще раз в блоке dispatch_async;)

- (void)requestMethod {

    NSMutableURLRequest *request = [NSMutableURLRequest
                                    requestWithURL:[NSURL URLWithString:[self.baseUrl
                                                                         stringByAppendingString:path]]];

    __weak typeof (self) weakSelf = self;
    NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
        NSUInteger responseStatusCode = [httpResponse statusCode];

        if (responseStatusCode != 200) {
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul), ^{
                [weakSelf requestMethod];
            });
        } else       
            completionBlock(results[@"result"][symbol]);
    }];
    [dataTask resume];

}

Ответ 2

Лучше иметь счетчик повторов, чтобы ваш метод не запускался навсегда:

- (void)someMethodWithRetryCounter:(int) retryCounter
{
    if (retryCounter == 0) {
        return;
    }
    retryCounter--;

    NSMutableURLRequest *request = [NSMutableURLRequest
                                    requestWithURL:[NSURL URLWithString:[self.baseUrl
                                                                         stringByAppendingString:path]]];

     __weak __typeof(self)weakSelf = self;

    NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
        NSUInteger responseStatusCode = [httpResponse statusCode];

        if (responseStatusCode != 200) {
            [weakSelf someMethodWithRetryCounter: retryCounter];
        } else
            completionBlock(results[@"result"][symbol]);
    }];
    [dataTask resume];
}

Его следует называть следующим образом:

[self someMethodWithRetryCounter:5];