iOS 12 SDK の NSURLSession が NSPOSIXErrorDomain (Code=53) で失敗することがある


iOS 12 SDK の NSURLSession が NSPOSIXErrorDomain (Code=53) で失敗することがある

以下の場合に NSPOSIXError で失敗することがあります

  1. Background Session ではない NSURLSession の通信中にアプリをバックグラウンドに移行し、フォアグラウンドへ戻すと失敗する
  2. iOS12の実機でwillEnterForegroundのタイミングで通信すると失敗する

本記事では、(1.) について説明します。
なお、この問題については AFNetworking/issue/4279 にて詳細に議論されています。
本記事の解決方法も概ね上記を参考にしています。

解決方法

解決方法は以下が考えられます

  • エラーの場合にリトライする
    • リクエストのべき等性が保証される場合、最もシンプルな解決法です
  • backgroundSessionConfiguration を使用する
    • 巨大なファイルのダウンロードなど、非常に時間がかかることが分かっている時は Background Session の使用を検討すべきです
  • UIApplication のバックグラウンドタスクを使用する
    • リクエストが比較的短時間 (180 秒以内程度) の場合、UIApplication の Backgraund Task が有効です
__block UIBackgroundTaskIdentifier bgTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
   [[UIApplication sharedApplication] endBackgroundTask:bgTaskId];
    bgTaskId = UIBackgroundTaskInvalid;
}];

[[session dataTaskWithURL:url
        completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            // do something...
        }] resume];

[[UIApplication sharedApplication] endBackgroundTask:bgTaskId];
bgTaskId = UIBackgroundTaskInvalid;

所感

この問題は以下の条件を満たさないと顕在化しないため、あまり問題にはならないかもしれません。

  • リクエストが完了するまで微妙に長い
  • Background Session を使用していない

また、Apple 側では解決済み……らしいので次のアップデートに含まれることを祈りましょう。

参考