を使用NSURLSession
してファイルから画像をアップロードするために、バックグラウンド モードで使用してNSURLSessionUploadTask
おり、デリゲート コールバックを使用しています。ユーザーによって殺されるのではなく、アプリがバックグラウンドに残っている場合、これはすべて完全に正常に機能します。
ただし、保留中のアップロードがまだあり、アプリがホーム画面を使用して強制終了された場合、アプリが再起動され、アップロードされなかった画像が、同じバックグラウンド識別子を持つ新しい NSURLSession を使用してアップロード タスクとして再キューイングされると、何か非常に奇妙なことが起こります。 :
1) タスクは一度だけ作成され、それが発生したときにタスクの説明を割り当て、NSURLSession
セッションごとに一意のタスク識別子も割り当てます。私のNSURLSession
バックグラウンドはシングルトンです。
2) タスクは、次のエラーでほぼ即座に失敗します。
Error Domain=NSURLErrorDomain Code=-999 "The operation couldn’t be completed. (NSURLErrorDomain error -999.)" UserInfo=0x174669880 {NSErrorFailingURLStringKey=myURL, NSURLErrorBackgroundTaskCancelledReasonKey=0
そして、完了デリゲート メソッドを呼び出します。
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
上記のエラーを渡します。この時点で、作成したタスクに一致するタスク識別子とタスクの説明を出力します。
NSURLSession
3) このすべてのタスクがほぼ即座に失敗した後、つまり事態がおかしくなり始めたとき、これらのすべてのタスクは何らかの形でコードに何もせずに再び に入れられます。決して失敗しません。2 回目は成功し、didCompleteWithError
今度はエラーなしで再度呼び出します。この時点で、タスクの説明とタスク識別子を出力すると、驚いたことに、割り当てた同じタスクの説明が返されますが、異なるタスク識別子が返されます! つまり、iOS は、失敗したと主張しているにもかかわらず、同じタスク識別子を使用してそのタスクを何らかの形で再作成し、再度キューに入れています。ネットワーク リクエストは Charles で 1 回しか確認できず、実際に失敗することはありません。
これは問題です。実際のアップロード エラーと iOS によって生成されたこの疑似エラーを区別できないためです。現在、これらのリクエストを明示的にキャンセルしていないため、キャンセルされたエラー コードを確認し、無視することを選択しています。タスクが魔法のように再キューされることを知っています。これは私には明らかなバグのように思えますが、いつでも再現できます。
回避策を講じると、すべてが期待どおりに機能しますが、これはハックであり、ある時点で実際のキャンセルを無視し、リクエストが実際に失敗したことをクライアントに通知しない可能性があると想像できます。
オンラインでこの問題について説明している人を数人しか見つけていませんが、回答はありません。
これに対して提出されたレーダーはありますか?これを防ぐ方法はありますか?
8.1 SDK を使用しています。