2

現在、写真とビデオのセットを S3 アマゾン サーバーに送信する必要があるプロジェクトに取り組んでいます。流れは次のようになります。

-まず、API に転送を開始するように依頼し、ID を取得します (API 呼び出し)

-transfer id -> api でファイルのアップロードを要求 -> 応答として file_id (api 呼び出し)

-file id -> api でのチャンク アップロードのリクエスト -> 応答としての amazon データ (api 呼び出し)

-upload chunck -> backgroundConfiguration で構成された NSURLSession 内 (アップロードごとに 5 MB)

-最後のチャンク アップロード (API 呼び出し) の後にファイルのアップロードを終了する

-最後のファイルアップロード後に転送を終了する(API呼び出し)


アプリがバックグラウンドで実行されている場合も、API を使用して呼び出しを行う必要があります。

そこで私が考えたのは、バックグラウンドでファイルをアップロードして完了ブロックを実行できる AFNetworking 2.0 を使用することでした。


その完了ブロックでは、コードは次のようになります。

 _managerBackground = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];


    - (void)uploadChunkInTheBackGround:(RequestChunkUploadResponse *)requestChunkUploadResponse
    {
        UploadChunkRequest *chunkUploadRequest = [[UploadChunkRequest alloc]initWithRequestChunkUploadResponse:requestChunkUploadResponse];

        APIService *weakSelf = (APIService *)self;

         NSURLSessionUploadTask *uploadTask = [_managerBackground uploadTaskWithRequest:chunkUploadRequest.request fromFile:chunkUploadRequest.fileLocationURL progress:nil completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
       //code to prepare recursive upload and files
        [weakSelf uploadChunkInTheBackGround:chunkUploadResponse];
    }];

難しいのは、コードを実行したり、iOS7 のバックグラウンドでアップロード タスクを実行したりすることです。

アプリがデバッガー (Xcode) に接続されている場合、上記のサンプルが機能します。ただし、コンソールに次のエラーが表示されます。

<BKProcessAssertion: 0x178468380> identifier: com.apple.nsnetworkd.handlesession process: YourApp[675] permittedBackgroundDuration: 30.000000 reason: backgroundDownload owner pid:111 preventSuspend  preventThrottleDownUI  preventIdleSleep  preventSuspendOnSleep

だからそれはクールではありません:(

コードを実行し、バックグラウンドでファイルをアップロードする方法はありますか..?? これについて何か経験はありますか?? それともiOS7の多くにお願いするのでしょうか??

あなたの考えを共有できることを願っています。

ありがとう、

敬具、

バート・スクーン

4

1 に答える 1

8

コンソールに表示されるエラーは、iOS によってバックグラウンド タスクに適用される 30 秒の制限です。NSURLSessionTask がバックグラウンドで完了したら。アプリはバックグラウンドで起動され、アプリは appDelegate で呼び出しを受け取ります。この時点で、完了ハンドラーを保存し、次のアップロード タスクをキューに入れ、完了ハンドラーを呼び出して、新しいスナップショットを取得し、アプリをスリープ状態に戻す必要があります。

- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler {

   // store completion handler

}

正確に 30 秒の制限が適用される時期がわかりません。以前のバージョンの iOS 7 バージョンでは、アプリがメモリから追い出されてから再起動された場合にのみ適用されていましたが、最新バージョン (7.0.3) では一時停止モードでも適用されることがあります。情報は Apple のドキュメントにあるので、試行錯誤に基づいて判断する必要があります。

あなたの問題は、完了ハンドラーを呼び出さずにバックグラウンドでアップロードを続行できることであり、それがアプリがクラッシュする理由だと思います。NSURLSession は、大量のファイルをバックグラウンドで継続的にアップロードすることを意図しているとは思いません。

これは、バックグラウンドで実行していて、すべての API 呼び出しがバックグラウンドで行われていると仮定すると、アップロードがどのように機能するかです。

1) タスクを作成して再開し、API を呼び出して ID を取得します - 完了ハンドラーを呼び出します。

2) バックグラウンドでタスクが終了し、アプリが起動します。30秒あるとしましょう。最初に、ID を取得するという応答を解析する必要があります。次に、ファイルのアップロードを要求する次のタスクをセットアップし、完了ハンドラーを呼び出します。

3) タスクがバックグラウンドで終了し、アプリが再び起動されます。これで、応答を解析してファイル ID を取得し、チャンク アップロードの次のタスクをセットアップして、完了ハンドラーを呼び出します。

基本的に要約すると、バックグラウンドでは、設定したすべてのタスクの後に完了ハンドラーを呼び出す必要があります。そうしないと、最終的にアプリがクラッシュします。

完了ハンドラーを呼び出すと、アップロードが非常に遅くなります。これは、必要に応じていつでもアプリを再起動するために iOS に依存しているためですが、現時点では、より良い解決策を見つけていません。

于 2013-11-15T21:20:40.127 に答える