Reputation: 1168
I would like to know how it is possible to continue a async NSURLConnection, which has been started in the foreground, when the app will be terminated. Currently I am starting a NSURLConnection when the app goes in the background. This works fine as long as the user is slower than the connection, when he wants to terminate the app. But when the user is quicker than it, the connection can't be established. Here is my code:
// AppDelegate.m
- (void)applicationDidEnterBackground:(UIApplication *)application
{
AnObject *newObject = [[AnObject alloc] init];
[newObject InactiveApp];
}
// AnObject.m
- (void)InactiveApp
{
self.backgroundTaskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];
// setting up the NSURLRequest
// [...]
dispatch_async(dispatch_get_main_queue(), ^
{
[NSURLConnection connectionWithRequest:request delegate:self];
});
}
// delegate functions, endBackgroundTask-closing, etc. is following
Unfortunately this is not working and I would like to know whether someone knows another way to fix it. There has to be a way which is similar like Snapchat or WhatsApp is doing it, because when you write an message and terminate the app right after pressing send, the message will be delivered.
The only way I could imagine is to do it with a background fetch but I think that is not the best solution, due to the fact that I just want to make one single connection when the App is send to the background.
Upvotes: 0
Views: 448
Reputation: 438277
I agree with Andy, that you should pursue NSURLSession
and a background NSURLSessionConfiguration
. See downloading content in the background section of the App Programming Guide for iOS: Background Execution.
By the way, the idea in your question will work fine (especially if you need support for iOS versions prior to 7.0, where NSURLSession
and its background sessions are not available). Two observations regarding your code snippet:
The way you've written it, would appear that your AnObject
would be prematurely deallocated when it falls out of scope and your app would therefore fail when it tried to call the delegate methods. Make sure to maintain a strong reference to AnObject
.
Don't forget to call endBackgroundTask
when the download is done. Likewise (and more subtly), the timeout handler should end the background task, too. See the Executing Finite Length Task section of the aforementioned App Programming Guide.
By the way, you mention requests continuing after the app is terminated. If a user manually terminates an app, that kills both background tasks contemplated in your question as well as background NSURLSession
tasks. These are intended to gracefully handle continuing tasks if the app leaves foreground, not if the user manually terminates the app. The NSURLSession
approach gracefully handles terminations due to memory pressure, but not manual termination.
Upvotes: 1