Task created in a session that has been invalidated

5.6k Views Asked by At

I am getting the following crash on crashlytics which I can not reproduce on my device

Fatal Exception: NSGenericException
Task created in a session that has been invalidated

at the following line

NSURLSessionTask *task = [self.session uploadTaskWithRequest:request fromFile:filePathURL];
[task resume];
[self.session finishTasksAndInvalidate];

I handled session invalidation at the delegate method

- (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(NSError *)error {
    // Crashlytics logging
    [CrashlyticsKit setBoolValue:true forKey:@"URLSession_didBecomeInvalid"];
    self.session = [self createNewSession];
}

- (NSURLSession *)CreateSession {
    NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:SERVER_URL];

    if (@available(iOS 11.0, *)) {
        sessionConfig.waitsForConnectivity = YES;
    }
    return [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];
}

after uploading a new build, I still have the same crash and no Crashlytics logs at "didBecomeInvalidWithError" at all!

any idea how to solve this crash?

1

There are 1 best solutions below

2
Rob On BEST ANSWER

If you invalidate a session, you cannot ever use it again. If you attempt to use a previously invalidated session, you’ll get that error you shared with us.

That leaves you with two options:

  • If you must invalidate a session, I’d recommend setting your session reference to nil so you can’t accidentally use it again. If you have to do another request later, you would instantiate a new session object.

  • If you might ever need to use the session again, you can simply refrain from invalidating it. The memory impact of keeping a single session object around is largely inconsequential. It only really an issue if you’re creating many sessions.

Frankly, background sessions are complicated enough that I’d need a pretty compelling case for dealing with multiple ones (e.g. each with its own completion handler passed to my app delegate). I’d lean towards the single background session pattern if possible.