web-dev-qa-db-ja.com

NSURLSessionバックグラウンドダウンロード-ネットワーク障害を介して再開

新しいiOS7API(NSURLSession)でのバックグラウンドダウンロードに関するAppleドキュメントを読んだ後、少しがっかりしました。Appleが管理していたと確信していました。バックグラウンドでのネットワーク可用性を介した一時停止/再開(またはそうするためのオプションを提供)が、…

したがって、ドキュメントを読むと、これが私たちが得たものです:

https://developer.Apple.com/library/ios/documentation/cocoa/Conceptual/URLLoadingSystem/NSURLSessionConcepts/NSURLSessionConcepts.html

タスクが完了すると、NSURLSessionオブジェクトはデリゲートのURLSession:task:didCompleteWithError:メソッドをエラーオブジェクトで呼び出すか、タスクが正常に完了した場合はnilを呼び出します。タスクが再開可能なダウンロードタスクである場合、NSErrorオブジェクトのuserInfoディクショナリにはNSURLSessionDownloadTaskResumeDataキーの値が含まれています。アプリは到達可能性APIを使用して再試行するタイミングを決定し、downloadTaskWithResumeData:またはdownloadTaskWithResumeData:completionHandler:を呼び出して、新しいダウンロードタスクを作成してそのダウンロードを続行する必要があります。手順3(タスクオブジェクトの作成と再開)に進みます。

これまでのところ私は解決策を理解していますが、私の質問は次のとおりです。ネットワークの損失を処理し、バックグラウンドでダウンロードを再開するのに最適なアーキテクチャは何ですか?

私の側では到達可能性を使用しており、ネットワークが利用可能になるたびに、すべてのタスクを再開し(作成時にNSArrayを介して参照)、ネットワークが失われるとそれらを一時停止します。これはフォアグラウンドでうまく機能しますが、バックグラウンドについては、次の点で助けが必要です。

  • アプリにフォアグラウンドで接続がない場合、接続せずにバックグラウンドに移動すると、すべてのタスクが中断されたままになり、ネットワークが利用可能な場合は戻ってきません…

  • バックグラウンドでネットワークを失い、すべてのダウンロード/タスクを停止します。シナリオ:

    • フォアグラウンドで、タスクのダウンロードを開始します
    • バックグラウンドに移動し、10秒後に「aireplanモード」に切り替えます
    • すべてのタスクでエラーが発生しました。したがって、メソッドURLSession:task:didCompleteWithError:downloadTaskWithResumeDataを使用して再開するか、再開できない場合(再開データが十分でないため)、再開せずに新しいタスクを作成しています(ネットワークがその状態に戻っている場合を除く)時間)。
    • それから私はwifiを上げました
    • 私はまだバックグラウンドにいるので、アプリケーションを起動せずにネットワークが戻ったときに「再開」をトリガーすることはできません…

これらの点にどのように対処しますか?私は何かを逃したことがありますか?

19
Nicolas Lauquin

私はまだバックグラウンドにいるので、アプリケーションを起動せずにネットワークが戻ったときに「再開」をトリガーすることはできません…


「バックグラウンドフェッチ」を使用すると、アプリがフェッチによって起動されたときに、ネットワークを確認してダウンロードタスクを再開できます。

3
gugupluto

バックグラウンド構成でNSURLSessionを作成する必要があります。そうすると、タスクがバックグラウンドデーモンに送信され、完了するとアプリが呼び出されます。

2
Zeev Vax

実装:

application:handleEventsForBackgroundURLSession:completionHandler:

アプリデリゲートでは、completionHandlerを呼び出さずに、デバイスが一時停止中に接続を失った後、アプリがバックグラウンドでハングします。そうすれば、アプリは到達可能性の通知をリッスンし、ネットワーク接続が再び利用可能になったときにダウンロードを再開できます。ただし、これはかなり危険なアプローチであり、Appleのアプリストア提出ガイドラインに合格しない可能性があります。さらに、このアプローチは、アプリがフォアグラウンドにあるときに接続が失われ、アプリが一時停止されている間に接続が回復した場合にはあまり役に立ちません。

最後に、私は次のことをしました:

  • application:handleEventsForBackgroundURLSession:completionHandler:通知を利用して、ダウンロードをバックグラウンドで一時停止しました。
  • 断続的なバックグラウンドフェッチ通知(つまり、application:performFetchWithCompletionHandler:completionHandler)を利用して、接続ステータスを確認し、一時停止したダウンロードを再開しました。 (ハットチップ@gugupluto)

これでも最適なダウンロードパフォーマンスが得られず、ユーザーがアプリを再度開いたときに「バックグラウンドダウンロード」が終了しないのはなぜかと思われるかもしれませんが、Appleから期待できる最善の方法のようです。今のところ。

2
gavdotnet