Лучшая практика для отправки большого количества данных в фоновом режиме на устройстве iOS4?


У меня есть приложение, которое должно отправлять данные (используя POST) на сервер. Эта функция должна быть на одном из субконтроллеров NavigationController, и пользователь должен иметь возможность перемещаться от этого контроллера и/или закрыть приложение (только iPhone4 / iOS4 будет поддерживаться). Должен ли я использовать потоки / NSOperations или / и отправлять данные с помощью существующих асинхронных методов? Есть идеи/рекомендации, как это реализовать?

5 21

5 ответов:

ОК, я отвечу на свой собственный вопрос. Во-первых, как сказал tc, лучше иметь этот вызов на делегате приложения, так что представление в NavigationController может быть закрыто. Во-вторых, отметьте начало фоновой обработки с помощью beginBackgroundTaskWithExpirationHandler: и завершите ее с помощью endBackgroundTask: следующим образом:

.h:

UIBackgroundTaskIdentifier bgTask;

.М:

- (void)sendPhoto:(UIImage *)image
{
  UIApplication *app = [UIApplication sharedApplication];

  bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ 
    [app endBackgroundTask:bgTask]; 
    bgTask = UIBackgroundTaskInvalid;
  }];


  NSLog(@"Sending picture...");

  // Init async NSURLConnection

  // ....
}

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

  NSLog(@"Picture sent.");

  UIApplication *app = [UIApplication sharedApplication];

  if (bgTask != UIBackgroundTaskInvalid) {
    [app endBackgroundTask:bgTask]; 
    bgTask = UIBackgroundTaskInvalid;
  }
}
У вас есть 10 минут до того, как iOS завершит работу вашего приложения. Вы можете проверить это время с помощью [app backgroundTimeRemaining]

Я бы просто использовал NSURLConnection. Это немного сложно, если вы хотите отправить multipart / form-data (см. SimpleURLConnections / PostController.м пример). Я бы вставил его в делегат приложения, но я такой ленивый.

Вы не должны беспокоиться о потоках вообще, если только неблокирующий ввод-вывод (т. е. NSURLConnection) не слишком медленный. Нить имеет свои собственные накладные расходы, и межпотоковое общение-это боль, и тупики ужасны.

То, что вам нужно сделать , это запустить фоновую задачу, чтобы разрешить приложению продолжать выполнение в фоновом режиме (завершить фоновую задачу в connectionDidFinishLoading: and connection:didFailWithError). Фоновым приложениям дается около 10 минут для завершения выполнения фоновых задач.

Используйте ASIHTTP и настройте очередь. Всю необходимую информацию вы можете найти здесь:

Http://allseeing-i.com/ASIHTTPRequest/

Это самый простой способ сделать то, что вы хотите сделать. Для отправки большого количества данных лучше отправлять их в фоновом режиме, чтобы пользовательский интерфейс оставался отзывчивым. ASIHTTPRequest предоставляет все методы, необходимые для запуска нескольких запросов (например, проверки выполнения, обратные вызовы и т. д.).

Его используют тонны отличных приложений для iPhone.

Я бы определенно предложил второй поток для любого длительно работающего процесса, который должен выполняться, пока пользователь делает что-то еще.

Еще одна вещь, о которой вам нужно будет подумать, - это то, что произойдет, если пользователь запустит процесс, а затем нажмет кнопку home. Как будет осуществляться взаимодействие с сервером, если его прервать? Может ли он продолжаться, когда пользователь в следующий раз входит в приложение? и т.д.

Я хотел бы поддержать сообщение, в котором упоминается:

bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ 
      [app endBackgroundTask:bgTask]; 

      bgTask = UIBackgroundTaskInvalid;
}];

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

Одно замечание об использовании очереди операций: что в этом случае вы действительно захотите отправить синхронный url-запрос из очереди. Это позволит вам не беспокоиться о параллельных операциях. Вот ссылка, которую вы можете найти полезной:

Http://www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/