Multitasking has always been a smart way to switch between apps. Multitasking allows apps to continue running in the background even after the user switches to another app. Multitasking has been supported in iOS since iOS 4, but it was quite restricted, operating only with music, location and voip. This becomes very frustrating when we need to download some content for an app in the background, but it isn’t supported. With iOS 7 Apple provided multitasking for almost every app. Now we can perform lots of task when an app is in the background.
By integrating the new multitasking APIs in iOS 7, the app can keep the content up-to-date. The new service allows your app to update information and download content in the background without draining the battery unnecessarily. The updates can happen at opportunistic times and are intelligently scheduled according to usage, so your app can update content in the background only when your users need it.
With iOS 6 and earlier, when an app goes to the background and is still executing a background task—if the device is then locked—the device will not go into sleep mode. It will be awake until the background task is completed. Whereas in iOS 7, the device will go to sleep shortly afterwards. Background tasks will execute at periodical intervals when the device is awake for any other tasks such as fetch mail, etc.
– New Multitasking API’s with iOS 7
– Background Fetch
– Remote Notifications
– Background Transfer Service
Background Fetch:
With this new API, an application will be able to fetch the new content and keep the content up-to-date so that users can see the new and interesting content when the app is opened without a waiting time.
Steps to enable this feature on the application:
1. Either in the info.plist or in the new Xcode feature capabilities, you can enable the background fetch by adding this key to UIBackgroundModes.
Include “UI Background Modes” key with “fetch” value in info.plist
2. To set a minimum background fetch interval that will allow your app to enable these fetches, just start with:
[app setMinimumBackgroundFetchInterval: UIApplicationBackgroundFetchIntervalMinimum]
We can set UIApplicationBackgroundFetchIntervalMinimum / UIApplicationBackgroundFetchIntervalNever or custom interval in seconds as background fetch interval. By Default it holds UIApplicationBackgroundFetchIntervalNever.
When there is no need to download the content in the background, we need to set UIApplicationBackgroundFetchIntervalNever.
3. To handle the new API/delegate method to download the content.
(void) application : (UIApplication *)application performFetchWithCompletionHandler:
(void(^) (UIBackgroundFetchResult))completionHandler
{
//fetch the latest content [_contentLoader downloadContentWithCompletionHandler:^
(BOOL didReceiveNewContent)
{
if(didReceiveNewContent)
{
completionHandler(UIBackgroundFetchResultNewData);
}
else
{
completionHandler(UIBackgroundFetchResultNoData);
}
}
}
Here one thing which is very important to remember after completing the download process—we have to tell iOS that the download is complete by using the “completion handler” in the method above, so that iOS can switch the app to a suspended state.
Remote Notifications:
With this new API, an application will be able to download the content when the app receives the push notification. This will be really very useful for developers—an app can download the push notification related content before the user sees the banner notification.
In addition to this, push notifications can omit the alert key and send it to the app as a silent notification. The app will not show any banner for this, but will be notified with the data availability. The application can load the data content before the next time an app opens to keep the app data up-to-date.
Steps to enable this feature on the application:
1. Either in the info.plist or in the new Xcode feature capabilities you can enable the remote notification by adding this key to UIBackgroundModes.
Include “UI Background Modes” key with “remote-notification” value in info.plist .
2. Set content available flag in push notifications to inform the app of the content available to download.
3. Handle the new API/delegate method to download the content.
- (void) application : (UIApplication *)application didReceiveRemoteNotification:
(NSDictionary *)userInfo performFetchWithCompletionHandler:(void(^)
(UIBackgroundFetchResult))completionHandler
{
//fetch the latest content
if(![[userInfo objectForKey:@"content-available"] intValue])
{
completionHandler(UIBackgroundFetchResultNoData);
return;
}
[_contentLoader downloadContentWithCompletionHandler:^(BOOL didReceiveNewContent){
if(didReceiveNewContent)
{
completionHandler(UIBackgroundFetchResultNewData);
}else
{
completionHandler(UIBackgroundFetchResultNoData);
}
}
}
Background Transfer Service:
In iOS 6, apps can transfer files while in the foreground or for a few minutes when the app returns to the background. It also could not effectively auto-download content or upload large assets.
iOS 7 provides a service to enqueue downloads and uploads that continue even after an app exits. It is not restricted by time and allows the enqueue of even large data.
Steps to use this feature on the application:
1. Create a background NSURLSession and figure it with NSURLSession configuration. We need to create a download or upload task using NSURLSessionTask with NSURLRequest and then enqueue it on NSURLSession by adding it to it.
2. Handle the new API/delegate method to handle the downloaded content.
- (void) application: (UIApplication *)application performFetchWithCompletionHandler:
(void(^) (UIBackgroundFetchResult))completionHandler
{
//fetch the latest content
//Create a Configuration Object
NSURLSessionConfiguration* sessionConfig =
[NSURLSessionConfiguration defaultSessionConfiguration];
nsConfig.allowsCellularAccess = YES;
//Create a Session
NSURLSession *dataDownloadSession = [NSURLSession sessionWithConfiguration: sessionConfig];
NSURL* fetchURL = [NSURL URLWithString:@"http://www.google.com"];
[dataDownloadSession dataTaskWithHTTPGetRequest:fetchURL completionHandler:^
(NSData* data, NSURLResponse* response, NSError* error)
{
NSLog(@"Fetch Completed");
completionHandler(UIBackgroundFetchResultNewData);
}];
}