У меня есть приложение, которому необходимо отправлять данные (используя POST) на сервер. Эта функция должна быть на одном из субконтроллеров NavigationController, и пользователь должен иметь возможность уйти от этого контроллера и/или закрыть приложение (будет поддерживаться только iPhone4/iOS4). Должен ли я использовать потоки/NSOperations или/и отправлять данные с использованием существующих асинхронных методов? Любые идеи/лучшие практики, как это реализовать?
Лучшая практика для отправки большого количества данных в фоновом режиме на устройстве iOS4?
Ответы (5)
Хорошо, я отвечу на свой вопрос. Во-первых, как сказал 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]
Я бы просто использовал NSURLConnection. Это немного сложно, если вы хотите отправить multipart/form-data (см. пример SimpleURLConnections/PostController.m). Я бы вставил его в делегат приложения, но я такой ленивый.
Вы вообще не должны беспокоиться о потоках, если только неблокирующий ввод-вывод (т.е. NSURLConnection) не слишком медленный. Многопоточность имеет свои накладные расходы, взаимодействие между потоками — это боль, а взаимоблокировки ужасны.
Что вам нужно сделать, так это запустить фоновую задачу, чтобы ваше приложение могло продолжать выполняться в фоновом режиме (завершите фоновую задачу в connectionDidFinishLoading: и connection:didFailWithError). Фоновым приложениям дается около 10 минут для завершения выполнения фоновых задач.
Используйте ASIHTTP и настройте очередь. Всю необходимую информацию можно найти здесь:
http://allseeing-i.com/ASIHTTPRequest/
Это самый простой способ добиться желаемого. Для отправки большого количества данных лучше отправлять в фоновом режиме, чтобы пользовательский интерфейс оставался отзывчивым. ASIHTTPRequest предоставляет все методы, необходимые для запуска нескольких запросов (например, проверки выполнения, обратные вызовы и т. д.).
Он используется множеством замечательных приложений для iPhone.
Я бы определенно предложил второй поток для любого длительного процесса, который необходимо запускать, пока пользователь делает что-то еще.
Еще одна вещь, о которой вам нужно подумать, это то, что произойдет, если пользователь запустит процесс, а затем нажмет кнопку «Домой». Как повлияет на взаимодействие с сервером прерывание? Может ли он продолжиться, когда пользователь в следующий раз войдет в приложение? и Т. Д.
Я хотел бы поддержать сообщение, в котором упоминается:
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
Но также обратите внимание, что вы можете также захотеть инкапсулировать свою единицу работы в подклассе NSOperation. Это сделает его чрезвычайно пригодным для повторного использования и, в сочетании с NSOperationQueue, автоматически обрабатывает потоки, а что нет. Позже, когда вы захотите изменить свой код или отобразить его в другом месте в своем приложении, его будет легко переместить или отредактировать.
Одно замечание об использовании очереди операций заключается в том, что в этом случае вы действительно захотите отправить синхронный запрос URL-адреса из очереди. Это позволит вам не беспокоиться о параллельных операциях. Вот ссылка, которая может оказаться полезной:
http://www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/