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

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

Ответы [ 5 ]

31 голосов
/ 15 октября 2010

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

.h:

UIBackgroundTaskIdentifier bgTask;

.m:

- (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]

4 голосов
/ 14 октября 2010

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

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

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

1 голос
/ 14 октября 2010

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

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

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

Он используется тоннами отличных приложений для iPhone.

0 голосов
/ 16 октября 2010

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

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

      bgTask = UIBackgroundTaskInvalid;
}];

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

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

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

0 голосов
/ 14 октября 2010

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

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

...