Сериализация запросов NSURLConnection (iOS) - использовать синхронный запрос? - PullRequest
0 голосов
/ 29 декабря 2011

Я перебираю список дат и отправляю запрос на веб-сервер для каждой даты в списке.

Я бы хотел, чтобы каждая дата была полностью обработана перед отправкой последующего запроса насервер.Для этого я настроил очередь последовательной отправки с использованием GCD.Каждый раз в цикле дат в очередь добавляется блок.

Проблема, с которой я сталкиваюсь, заключается в том, что мое NSURLConnection устанавливается с использованием стандартного асинхронного вызова.Это приводит к тому, что запросы не блокируют любые последующие запросы.Таким образом, они перекрывают друг друга.

Мой вопрос: это тот случай, когда для меня имеет смысл использовать синхронный NSURLConnection (в очереди отправки) или есть какой-то другой способзаставить его работать с помощью стандартного асинхронного вызова?

Ответы [ 2 ]

2 голосов
/ 29 декабря 2011

Есть несколько способов сделать это.Какой бы метод вы ни выбрали, запуск соединения должен быть привязан к завершению вашей задачи обработки.

  1. В каждом блоке, добавляемом в вашу последовательную очередь, используйте синхронный запрос.Это, вероятно, самое быстрое решение, учитывая вашу текущую реализацию, если вы согласны с ограниченной обработкой ошибок синхронного запроса.

  2. Не используйте последовательную очередь.Запустите первое асинхронное соединение и обработайте ответ.После завершения обработки запустите следующее асинхронное соединение.Промыть и повторить.

1 голос
/ 29 декабря 2011

Я думаю, что использование синхронного API NSURLConnection - хорошая идея.У вас есть несколько других вариантов.Можно было бы написать объект-оболочку вокруг NSURLConnection, который использовал асинхронные API-интерфейсы NSURLConnection, чтобы вы получили полезную информацию, которую предоставляют асинхронные обратные вызовы API, включая ход загрузки, вы можете легко продолжать обновлять свой пользовательский интерфейс во время выполнения запроса, нопредставляет свой собственный синхронный метод для выполнения всего, что вам нужно.По сути, что-то вроде:

@implementation MyURLConnectionWrapper

- (BOOL)sendRequestWithError:(NSError **)error
{
    error = error ? error : &(NSError *){ nil };

    self.finishedLoading = NO;
    self.connectionError = nil;
    self.urlConnection = [][NSURLConnection alloc] init...]

    while (!self.finishedLoading) 
    {
        [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: [NSDate distantFuture]];
    }

    if (self.connectionError != nil)
    {
        *error = self.connectionError;
        return NO;
    }

    return  YES;
}

@end

(Это все напечатано на макушке головы и сильно сокращено, но должно дать вам основную идею.)

Вы также можете сделатьчто-то вроде запуска каждого запроса в методе завершения делегирования для предыдущего, полностью отказывающегося от использования очереди последовательной отправки:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
{
    [self sendNextRequest];
}

В любом случае вам нужно подумать о том, как правильно обрабатывать ошибки соединения.Я успешно использовал оба подхода в разных местах.

...