AFNetworking error 53 during attempted background fetch
Asked Answered
H

2

9

While updating my application to support Background App Refresh I ran into problem with AFNetworking.

I am getting NSPOSIXErrorDomain Code=53 "Software caused connection abort". The problem seems to occur in iOS 12, where the background connection gets terminated.

AFNetworking 2.6.3 is used to make the fetch.

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) {

           }
    ];
}

Console output:

[Error] GET '(null)' (0) [31.9163 s]: Error Domain=NSPOSIXErrorDomain Code=53 "Software caused connection abort" UserInfo={NSErrorFailingURLStringKey=https://www.example.com/orders, _kCFStreamErrorDomainKey=1, NSErrorPeerAddressKey={length = 16, capacity = 16, bytes = 0x100201bb3e80187c0000000000000000}, _kCFStreamErrorCodeKey=53, NSErrorFailingURLKey=https://www.example.com/orders}

Hubie answered 14/11, 2018 at 9:47 Comment(2)
Does your app support fetch Background Mode?Cubage
@Cubage Yes background fetch capability is switched on, even performFetchWithCompletionHandler is getting called.Hubie
H
10

Starting the fetch as background task with 0.1 sec delay solved the problem:

-(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;
                           }
        ];
    });
}
Hubie answered 15/11, 2018 at 9:24 Comment(3)
I get this error whenever I push home button in between download process.Huston
Looking at the original post - [OrdersService performFetch] is implemented in an async manner, where it will return once its requested from the network, but before its processed any response. This means your completion handler of new data is likely run, before networking has completed, resulting in your app being re-suspended and then aborting the open network call - adding a delay is likely letting the network run a bit longer - but ideally you'd call the completion handler once either the success or failure block has been run. Hope this helps.Altimeter
this works for me as well - is it safe to reduce 0.1 seconds to a lower duration?Pauper
A
2

Some of the solutions linked below were helpful to resolve Lower protocol stack error: 53.

Informative thread on AFNetworking GitHub with relevant details and background info: AFNetworking issue

Do read the comment towards the end for insightful details:

In terms of workarounds, there’s three things you can do here, and it may make sense to do all three, or some subset, depending on the requirements of your real app. To wit:

A. If you regularly bounce in and out of your app — for example, you bounce the user out to Safari so that they can do some authentication task and then you want Safari to bounce the user back to your app — it might make sense to use a UIApplication background task to prevent your app from being suspended during those bounces.

This approach will only keep your app running for a few minutes, but if that’s sufficient for common user scenarios then it’s worthwhile doing.

B. You can retry requests yourself. Even if you weren’t running into this problem this is generally a good idea. There’s a vast array of transient issues that can cause requests to fail, and a single retry will often get you past the error without further remedial work.

The obvious gotcha here is idempotency. You can retry idempotent requests without any worries, but you’ll need some cunning app-specific logic if you want to retry non-idempotent requests.

C. You can invalidate your session when you go into the background and then re-create the session when you come back into the foreground. The new session will not share any connections with the old one, so this problem just can’t occur.

As I mentioned earlier, combining approaches might make sense. For example, A and C work together well, allowing you to avoid the cost of session invalidation unless you run out of background execution time. And you might want to do B because it has benefits outside of this problem space.

In my case, it's happening on iOS12.3 device

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

Preparing your app to run in background mode: Apple's doc: How to do background fetch

Also, good source of info on background tasks: apple dev forum

Account answered 6/8, 2019 at 1:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.