10

私は、ユーザーがサーバーを使用してビデオを録画してサーバーに送信できるアプリに取り組んでいAVFoundationます。ビデオの最大サイズは、インターネットの速度とタイプに応じて最大15Mですが、サーバーにビデオを転送するのに約1〜5分かかる場合があります。 。ビデオがサーバーにアップロードされている間、ユーザーがアプリで他の作業を続行できるように、記録されたビデオをバックグラウンドスレッドでサーバーに転送しています。

バックラウンドで長時間実行されるタスクを実装するためのAppleDocsを読んでいると、バックグラウンドで実行できるアプリの種類はごくわずかであることがわかります。
例えば

音声-アプリは、バックグラウンドでユーザーに音声コンテンツを再生します。(このコンテンツには、AirPlayを使用したオーディオまたはビデオコンテンツのストリーミングが含まれます。)

アプリをバックグラウンドで実行することもできますか?または、メインスレッドでビデオを転送する必要がありますか?

4

3 に答える 3

13

NSOperationQueueメインスレッドのブロックを回避するためにマルチスレッドタスクを実行するための推奨される方法です。バックグラウンドスレッドは、GPS表示やオーディオストリーミングなど、アプリケーションが非アクティブのときに実行するタスクに使用されます。

アプリケーションがフォアグラウンドで実行されている場合は、バックグラウンドスレッドはまったく必要ありません。

単純なタスクの場合、ブロックを使用してキューに操作を追加できます。

NSOperationQueue* operationQueue = [[NSOperationQueue alloc] init];
[operationQueue addOperationWithBlock:^{
    // Perform long-running tasks without blocking main thread
}];

NSOperationQueueその使用方法に関する詳細情報。

アップロードプロセスはバックグラウンドで続行されますが、アプリケーションは一時停止される可能性があるため、アップロードがキャンセルされる場合があります。これを回避するには、次のコードをアプリケーションデリゲートに追加して、アプリを一時停止する準備ができたことをOSに通知します。

- (void)applicationWillResignActive:(UIApplication *)application {
    bgTask = [application beginBackgroundTaskWithExpirationHandler:^{

      // Wait until the pending operations finish
      [operationQueue waitUntilAllOperationsAreFinished];

      [application endBackgroundTask: bgTask];
      bgTask = UIBackgroundTaskInvalid;
    }]; 
}
于 2013-03-07T10:36:19.203 に答える
5

Dwayneへの応答から、バックグラウンドモードでダウンロードできる必要はありません。むしろ、必要なのは、メインスレッドの横にある別のスレッド(バックグラウンドスレッド)でダウンロードを行うことです。GCDの場合は次のようになります。

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//        Do you download here...
    });
于 2013-03-07T11:49:50.410 に答える
4

要件は、バックグラウンドで実行する資格があります。infoplistでサポートされているバックグラウンドモードを登録する必要はありません。アプリがバックグラウンドに移行しようとしているときに、バックグラウンドタスクハンドラーを使用して追加の時間を要求し、そのブロックでタスクを実行するだけです。OSによって強制的に終了されないように、必ず10分前にハンドラーを停止してください。

Appleの以下のコードを使用できます。

- (void)applicationDidEnterBackground:(UIApplication *)application
{
bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
    // Clean up any unfinished task business by marking where you
    // stopped or ending the task outright.
    [application endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
}];

// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    // Do the work associated with the task, preferably in chunks.

    [application endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
});}
于 2013-03-07T10:42:59.043 に答える