サーバーに(POSTを使用して)データを送信する必要があるアプリがあります。この機能は、NavigationControllerサブコントローラーの1つにある必要があり、ユーザーはこのコントローラーから離れたり、アプリを閉じたりできる必要があります(iPhone4 / iOS4のみがサポートされます)。スレッド/NSOperationsを使用するか、または/および既存の非同期メソッドを使用してデータを送信する必要がありますか?これを実装するためのアイデア/ベストプラクティスはありますか?
5 に答える
OK、私は自分の質問に答えます。まず、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;
}
}
iOSがアプリを終了するまでに10分あります。今回はで確認できます[app backgroundTimeRemaining]
NSURLConnectionを使用します。multipart / form-dataを送信する場合は少し注意が必要です(SimpleURLConnections / PostController.mの例を参照)。私はそれをアプリデリゲートに貼り付けますが、私はそのように怠惰です。
非ブロッキングI/O(つまり、NSURLConnection)が遅すぎない限り、スレッドについてまったく心配する必要はありません。スレッドには独自のオーバーヘッドがあり、スレッド間の通信は苦痛であり、デッドロックはひどいものです。
あなたがする必要があるのは、バックグラウンドタスクを開始して、アプリがバックグラウンドで実行し続けることを可能にすることです(connectionDidFinishLoading:とconnection:didFailWithErrorでバックグラウンドタスクを終了します)。バックグラウンドアプリは、バックグラウンドタスクの実行を完了するために約10分与えられます。
ASIHTTPを使用して、キューを設定します。必要なすべての情報はここにあります:
http://allseeing-i.com/ASIHTTPRequest/
これは、達成したいことを達成するための最も簡単な方法です。大量のデータを送信する場合は、UIの応答性を維持するために、バックグラウンドで送信することをお勧めします。ASIHTTPRequestは、複数のクエリを開始するために必要なすべてのメソッド(つまり、進行状況チェック、コールバックなど)を提供します。
たくさんの素晴らしいiPhoneアプリで使用されています。
ユーザーが何か他のことをしている間に実行する必要がある長時間実行プロセスには、間違いなく2番目のスレッドをお勧めします。
考慮する必要があるもう1つのことは、ユーザーがプロセスを開始してからホームボタンを押した場合に何が起こるかということです。サーバーの相互作用は、中断されることによってどのように影響を受けますか?ユーザーが次にアプリに入ったときに続行できますか?等
次のような投稿をサポートしたいと思います。
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
ただし、作業単位をNSOperationサブクラスにカプセル化することもできます。これにより、非常に再利用可能になり、NSOperationQueueと組み合わせると、スレッド化などを自動的に処理します。その後、コードを変更したり、アプリ内の別の場所にコードを表示したりする場合は、移動や編集が簡単になります。
操作キューの使用に関する1つの注意点は、この場合、実際にはキュー内から同期URL要求を送信する必要があるということです。これにより、並行操作について心配する必要がなくなります。役立つと思われるリンクは次のとおりです。
http://www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/