Downloading Content in the Background
Yes it is possible.
You primary have the options to use a scheduled task or execute a code block with a push notification. In my opinion it's easiest with a scheduled task, but I have have experienced that the task is not always executed. So if your app rely on the background fetch you should check if the data is downloaded at application:willEnterForeground
and download data if new data is not available.
Here's the link to the Objective-c documentation on the topic: Background Execution
Objective-c:
The process for creating a configuration object that supports background downloads is as follows:
- Create the configuration object using the backgroundSessionConfigurationWithIdentifier: method of NSURLSessionConfiguration.
- Set the value of the configuration object’s sessionSendsLaunchEvents property to YES.
- if your app starts transfers while it is in the foreground, it is recommend that you also set the discretionary property of the configuration object to YES.
- Configure any other properties of the configuration object as appropriate.
- Use the configuration object to create your NSURLSession object.
Once configured, your NSURLSession object seamlessly hands off upload and download tasks to the system at appropriate times. If tasks finish while your app is still running (either in the foreground or the background), the session object notifies its delegate in the usual way. If tasks have not yet finished and the system terminates your app, the system automatically continues managing the tasks in the background. If the user terminates your app, the system cancels any pending tasks.
When all of the tasks associated with a background session are complete, the system relaunches a terminated app (assuming that the sessionSendsLaunchEvents property was set to YES and that the user did not force quit the app) and calls the app delegate’s application:handleEventsForBackgroundURLSession:completionHandler:
method. (The system may also relaunch the app to handle authentication challenges or other task-related events that require your app’s attention.) In your implementation of that delegate method, use the provided identifier to create a new NSURLSessionConfiguration and NSURLSession object with the same configuration as before. The system reconnects your new session object to the previous tasks and reports their status to the session object’s delegate.
Since I code using Swift I'll provide some documentation on that.
Swift 3.0
- Create a Scheduler
To initialize a scheduler, call init(identifier:) for NSBackgroundActivityScheduler, and pass it a unique identifier string in reverse DNS notation (nil and zero-length strings are not allowed) that remains constant across launches of your application.
let activity = NSBackgroundActivityScheduler(identifier: "com.example.MyApp.updatecheck")
The system uses this unique identifier to track the number of times the activity has run and to improve the heuristics for deciding when to run it again in the future.
- Configure Scheduler Properties
There's several properties you could configure, check the API reference for that.
E.G:
Scheduling an activity to fire once each hour
activity.repeats = true
activity.interval = 60 * 60
- Schedule Activity with scheduleWithBlock:
When your block is called, it’s passed a completion handler as an argument. Configure the block to invoke this handler, passing it a result of type NSBackgroundActivityScheduler.Result to indicate whether the activity finished (finished) or should be deferred (deferred) and rescheduled for a later time. Failure to invoke the completion handler results in the activity not being rescheduled. For work that will be deferred and rescheduled, the block may optionally adjust scheduler properties, such as interval or tolerance, before calling the completion handler.
activity.scheduleWithBlock() { (completion: NSBackgroundActivityCompletionHandler) in
// Perform the activity
self.completion(NSBackgroundActivityResult.Finished)
}
Notes to remember:
Apps only get ~ 10 mins (~3 mins as of iOS 7) of background execution - after this the timer will stop firing.
As of iOS 7 when the device is locked it will suspend the foreground app almost instantly. The timer will not fire after an iOS 7 app is locked.