Обработка ASIHTTPRequest нескольких запросов - PullRequest
3 голосов
/ 05 июля 2011

Я боролся с этой проблемой более недели. И мне действительно нужна помощь.

Я использую ASIHTTPRequest для обработки трех разных запросов на загрузку. Первый запрос на загрузку будет загружать из онлайн .txt файла временную метку. В соответствии с этой отметкой времени он должен обрабатывать запуск приложения.

Он проверит, была ли временная метка ранее сохранена в NSUserDefaults, если нет, то это первый раз, когда приложение запускается, и оно загружает фид JSON (используя ASIHTTPRequest), а затем анализирует его в Core Data. ,

Если сохраненная временная метка совпадает с онлайн-меткой, то ничего не происходит, поскольку данные обновлены.

Если сохраненная временная карта старше, чем онлайн-отметка времени, то база данных будет очищена и перезагружена.

Моя проблема в том, что в ASIHTTPRequest до выполнения requestFinished выполнение application:didFinishLaunchingWithOptions выполняется до конца. Сейчас в начале application:didFinishLaunchingWithOptions я прошу ASIHTTPRequest загрузить онлайн-метку времени. Перед тем, как application:didFinishLaunchingWithOptions закончится, мне нужно загрузить онлайн-метку и подготовить ее к использованию. Как бы я это сделал? Проблема с ASIHTTPRequest в том, что он начинает выполняться после окончания application:DidFinishLaunchingWithOptions.

Ответы [ 3 ]

8 голосов
/ 05 июля 2011

Без кода, наши ответы должны быть довольно общими.Но для меня это звучит так, как будто вам нужно полностью изменить процесс запуска.

Если важно, чтобы ваши http-запросы выполнялись по порядку, вам нужно вызывать их по порядку - вложенные в методы делегата завершения друг друга.Вы можете использовать поле .userInfo ASIHTTPRequest для определения различных типов запросов, которые вы запускаете.

Ваш didFinishLaunching метод должен просто сделать достаточно для запуска вашего первого запроса (и, возможно, вызвать «загрузку»).представление), тогда остальная часть работы по запуску приложения должна быть сделана различными requestDidFinish методами.

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

РЕДАКТИРОВАТЬ: Вот некоторый код для описаниячто я имею в виду под «вложенными в методы завершения друг друга».Обратите внимание, что я просто набрал это прямо здесь, так что не просто скопируйте и вставьте это и ожидайте что-нибудь вроде разумного поведения.

// inside didFinishLaunching
ASIHTTPRequest *myInitialRequest = [ASIHTTPRequest requestWithURL:myNSURL];
myInitialRequest.userInfo = [NSDictionary dictionaryWithObject:@"initial" forKey:@"type"];
myInitialRequest.delegate = self;
[myInitialRequest startAsynchronous];
// and then NOT other setup stuff that depends on this data.


-requestDidFinish:(ASIHTTPRequest *)request
{
    if ([[request.userInfo objectForKey:@"type"] isEqualToString:@"initial"]) {
        //you just used the userinfo field to differentiate this from other requests
        //do whatever here, and then make your next request HERE.

        ASIHTTPRequest *nextRequest = [ASIHTTPRequest requestWithURL:myNextURL];
        nextRequest.delegate = self;
        nextRequest.userInfo = [NSDictionary dictionaryWithObject:@"next" forKey:@"type"];
        [nextRequest startAsynchronous];
    }
    if ([[request.userInfo objectForKey:@"type"] isEqualToString:@"next"]) {
        // so now you know this is your "next" type request coming back to you.

        // ... so do whatever you do with this, and then HERE do the rest of your
        // app setup and launch business.
    }
}

Итак, вы настраиваете запрос с полем userInfo, которое его идентифицирует, а затемдифференцировать обработку своего ответа на основе этого поля.В любом случае это базовое значение для использования более одного ASIHTTPRequest в контроллере представления.

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

Кстати, вы также можете указать метод обработчика завершения или использовать интерфейс блока, чтобы указать, что ASIHTTPRequest делает по завершении.Но я думаю, что загрузка ваших запросов с определением полей userInfo и последующей обработкой ваших ответов в одном месте - это самый чистый подход.

2 голосов
/ 05 июля 2011

Вы не можете сделать это таким образом. Проблема в том, что запрос асинхронный. Вы не можете изменить его на синхронный, потому что в случае каких-либо сетевых задержек iOS прекратит работу приложения из-за слишком долгой загрузки.

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

0 голосов
/ 05 июля 2011

Как правильно заметил Джим, проблема в асинхронном запросе к вашему серверу.Метод application: didFinishLaunchingWithOptions продолжает выполнение после асинхронного вызова сервера.Ваш запрос к серверу может занять некоторое время, и к тому времени метод application: didFinishLaunchingWithOptions может быть не в своем цикле.Поэтому единственное решение для этого - сделать синхронный вызов серверу и сделать «application: didFinishLaunchingWithOptions», чтобы дождаться ответа сервера с ответом и затем продолжить выполнение следующей инструкции.Вы можете достичь этого, используя метод startSynchronous ASIHTTPRequest.

...