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?
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.