バックグラウンドアプリの更新をサポートするようにアプリケーションを更新しているときに、AFNetworkingで問題が発生しました。
NSPOSIXErrorDomain Code=53 "Software caused connection abort"
。この問題は、バックグラウンド接続が終了するiOS 12で発生するようです。
AFNetworking 2.6.3を使用してフェッチを行います。
AppDelegate.m
:
- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
[OrdersService performFetch];
completionHandler(UIBackgroundFetchResultNewData);
}
OrdersService.m
:
-(void) performFetch {
[[AFHTTPRequestOperationManager new] GET:@"https://www.example.com/orders"
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}
];
}
コンソール出力:
[エラー] GET '(null)'(0)[31.9163 s]:エラードメイン= NSPOSIXErrorDomainコード= 53「ソフトウェアが接続を中止しました」UserInfo = {NSErrorFailingURLStringKey = https://www.example.com/orders 、_ kCFStreamErrorDomainKey = 1、NSErrorPeerAddressKey = {length = 16、容量= 16、バイト= 0x100201bb3e80187c0000000000000000}、_kCFStreamErrorCodeKey = 53、NSErrorFailingURLKey = https://www.example.com/orders }
0.1秒の遅延でフェッチをバックグラウンドタスクとして開始すると、問題が解決しました。
-(void) performFetch {
__block UIBackgroundTaskIdentifier bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithName:@"GET /orders" expirationHandler:^{
// EXPIRED
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task, preferably in chunks.
[[AFHTTPRequestOperationManager new] GET:@"https://www.example.com/orders"
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
// SUCCESS
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// FAILURE
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
];
});
}
以下にリンクされているソリューションのいくつかは、解決に役立ちましたLower protocol stack error: 53
。
関連する詳細と背景情報を含むAFNetworking GitHubの有益なスレッド: AFNetworkingの問題
洞察に満ちた詳細については、最後に向かってコメントを読んでください:
回避策に関しては、ここで3つのことを実行できます。実際のアプリの要件に応じて、3つすべて、または一部を実行することが理にかなっている場合があります。ウィットするには:
A.アプリを定期的にバウンスする場合(たとえば、ユーザーをSafariにバウンスして、ユーザーが認証タスクを実行できるようにしてから、Safariにユーザーをアプリにバウンスさせたい場合)は、 UIApplicationバックグラウンドタスクを使用して、バウンス中にアプリが中断されるのを防ぎます。
このアプローチは、アプリを数分間実行し続けるだけですが、それが一般的なユーザーシナリオに十分である場合は、実行する価値があります。
B.リクエストを自分で再試行できます。この問題に遭遇していなかったとしても、これは一般的に良い考えです。リクエストが失敗する原因となる可能性のある一時的な問題が数多くあります。1回の再試行で、多くの場合、追加の修正作業なしでエラーを回避できます。
ここで明らかな問題は、べき等です。心配することなくべき等要求を再試行できますが、べき等でない要求を再試行する場合は、アプリ固有の狡猾なロジックが必要になります。
C.バックグラウンドに移動したときにセッションを無効にし、フォアグラウンドに戻ったときにセッションを再作成することができます。新しいセッションは古いセッションとの接続を共有しないため、この問題は発生しません。
先に述べたように、アプローチを組み合わせることは意味があるかもしれません。たとえば、AとCは連携して機能するため、バックグラウンド実行時間が不足しない限り、セッションの無効化によるコストを回避できます。そして、あなたはBをしたいと思うかもしれません。なぜなら、それはこの問題空間の外に利点を持っているからです。
私の場合、それはiOS12.3
端末
2019-08-05 17:38:50.988880-0700 myApp[2988:1589883] [BoringSSL] nw_protocol_boringssl_error(1584) [C15.1:4][0x10dd6e700] Lower protocol stack error: 53
2019-08-05 17:38:50.990132-0700 myApp[2988:1589883] TIC Read Status [15:0x281d59d40]: 1:53
2019-08-05 17:38:50.995585-0700 myApp[2988:1589883] Task <D62956CC-6C2B-4D5E-B1DA-0A5CA2BB60EF>.<1> HTTP load failed (error code: 53 [1:53])
2019-08-05 17:38:51.000334-0700 myApp[2988:1588479] Task <D62956CC-6C2B-4D5E-B1DA-0A5CA2BB60EF>.<1> finished with error - code: 53
アプリをバックグラウンドモードで実行するための準備: Appleのドキュメント:バックグラウンドフェッチの方法
また、バックグラウンドタスクに関する情報の優れた情報源: Apple開発フォーラム