7

在更新我的应用程序以支持后台应用程序刷新时,我遇到了 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]: Error Domain=NSPOSIXErrorDomain Code=53 "软件导致连接中止" UserInfo={NSErrorFailingURLStringKey= https://www.example.com/orders , _kCFStreamErrorDomainKey=1 , NSErrorPeerAddressKey={长度 = 16, 容量 = 16, 字节 = 0x100201bb3e80187c0000000000000000}, _kCFStreamErrorCodeKey=53, NSErrorFailingURLKey= https://www.example.com/orders }

4

2 回答 2

9

以 0.1 秒的延迟启动 fetch 作为后台任务解决了这个问题:

-(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;
                           }
        ];
    });
}
于 2018-11-15T09:24:20.513 回答
2

下面链接的一些解决方案有助于解决Lower protocol stack error: 53.

AFNetworking GitHub 上的信息线程,包含相关详细信息和背景信息:AFNetworking 问题

请阅读最后的评论以获得有见地的细节:

就解决方法而言,您可以在这里做三件事,根据实际应用程序的要求,做所有这三件事或某些子集可能是有意义的。以机智:

A. 如果您定期进出您的应用程序 - 例如,您将用户退回到 Safari,以便他们可以执行一些身份验证任务,然后您希望 Safari 将用户退回到您的应用程序 - 这可能是有意义的使用 UIApplication 后台任务来防止您的应用程序在这些反弹期间被暂停。

这种方法只会让你的应用程序运行几分钟,但如果这对于常见的用户场景来说足够了,那么它是值得的。

B. 您可以自己重试请求。即使您没有遇到此问题,这通常也是一个好主意。存在大量可能导致请求失败的暂时性问题,单次重试通常会让您在没有进一步补救工作的情况下克服错误。

这里明显的问题是幂等性。您可以毫无顾虑地重试幂等请求,但如果您想重试非幂等请求,则需要一些巧妙的特定于应用程序的逻辑。

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 的文档:How to do background fetch

此外,有关后台任务的良好信息来源:apple dev forum

于 2019-08-06T01:09:43.070 回答