Difference between revisions of "IOS 7 Multitasking, Background Transfer Service and Fetching"
m (Text replacement - "<google>BUY_IOS7</google>" to "<htmlet>ios9_upgrade</htmlet>") |
m (Text replacement - "<table border="0" cellspacing="0">" to "<table border="0" cellspacing="0" width="100%">") |
||
(5 intermediate revisions by the same user not shown) | |||
Line 167: | Line 167: | ||
+ | |||
+ | <htmlet>ezoicbottom</htmlet> | ||
<hr> | <hr> | ||
<table border="0" cellspacing="0" width="100%"> | <table border="0" cellspacing="0" width="100%"> |
Latest revision as of 20:03, 27 October 2016
Previous | Table of Contents | Next |
Integrating iAds into an iOS 7 App | An iOS 7 Background Transfer Service Tutorial |
Learn SwiftUI and take your iOS Development to the Next Level |
Multitasking refers to the ability of an operating system to run more than one application concurrently. The introduction of iOS version 4.0 was met with much fanfare relating to the fact that the operating system now supported multitasking. In actual fact, iOS has always been able to support multitasking and many of the applications bundled with the device (such as the Mail, Phone and Music apps) have been leveraging the multitasking abilities of iOS since the very first iPhone shipped. What was, in fact, significant about iOS 4 was that some (though not all) of the multitasking capabilities of the operating system were now being made available to us as third party application developers. These capabilities are, unsurprisingly, still available in iOS 7 along with some new features not available in previous iOS releases.
Multitasking in iOS, within the context of third party application development at least, is not without some restrictions however. The goal of this chapter, therefore, is to provide an overview of the capabilities, limitations and implementation of multitasking in iOS 7, including an overview of new features such as the background transfer service and background fetch.
Understanding iOS Application States
At any given time an iOS application can be in one of a number of different states. Applications in the not running state have either yet to be launched by the user or were previously launched but have been terminated either by the user or the operating system.
An application is in the foreground state when it is the current application displayed to the user. At any one time only one application can be in the foreground state. Applications in the foreground can be in one of two sub-states, namely active or not active. When in the not active state, the application is running in the foreground but is not actively receiving or handling any events (for example because the system is awaiting a user response to an event such as an incoming phone call or because the screen lock has been activated). An active application, on the other hand, is running in the foreground and currently receiving events (perhaps due to interaction with the user or via the network).
An application is considered to be in the background state when it is no longer the foreground application. Applications in this state are still executing code either because they have requested additional background execution time to complete a task or because they have requested permission to remain running in the background and, in so doing, have met the criteria (discussed later in the chapter) to do so. An application typically enters the background when the user launches another application, or brings another background application into the foreground. With iOS 4.0 or later it is also possible to launch an application directly into the background.
Applications enter the suspended state when they have been moved to the background and are no longer executing code. The application is still stored in memory preserving its state at the point of suspension but is neither using any CPU cycles nor is it placing additional load on the battery. This state of suspended animation allows the application to be quickly moved into the foreground and execution resumed at the request of the user thereby providing near instantaneous application switching. Suspended applications may be terminated at any time at the discretion of the operating system (typically in order to free up memory resources) so it is essential that applications save any status information to non-volatile storage prior to entering the suspended state.
A Brief Overview of the Multitasking Application Lifecycle
The lifecycle of an iOS 7 application primarily involves a series of transitions between the various states outlined in the preceding section. At each stage of the lifecycle, calls are made to specific methods in the application’s delegate so that the application can take appropriate action where necessary. When an application is launched it transitions from not running to either the active or background state. Once the application has loaded the didFinishLaunchingWithOptions delegate method is called. If the newly launched application is entering foreground mode the applicationDidBecomeActive method is then called. If, on the other hand the application is moving directly to the background state (either by design or by necessity), then the applicationDidEnterBackground delegate method is triggered.
When a foreground application enters the background the application transitions to the inactive state, triggering a call to the application delegate’s applicationWillResignActive method. This in turn is followed by a transition to background status which is accompanied by a call to the applicationDidEnterBackground method.
If the application has not indicated that it is eligible to continue running in the background the application is given 5 seconds to complete any tasks before returning from the applicationDidEnterBackground method. If these tasks cannot be performed in the time given they may be performed by making a call to the beginBackgroundTaskWithExpirationHandler method followed by a call to the endBackgroundTask method when the task is complete. Failure to return from the applicationDidEnterBackground method within the allocated time will result in the application being terminated. Apple has also introduced a slight change in the way in which extra time is provided to complete a task in iOS 7. In iOS 6, for example, if the user put the device into sleep mode by locking the screen whilst an application was completing tasks, the device would be kept awake until the tasks were complete. With iOS 7, however, the tasks are suspended when the device goes to sleep and then given small bursts of time to progress the tasks when the device wakes up to perform other tasks such as checking email. Network based tasks should, therefore, be wrapped in NSURLSession instances in order to handle the intermittent nature of this background execution environment.
When an application is moved from the background to the foreground, the applicationWillEnterForeground method is triggered, followed by a call to applicationDidBecomeActive.
Finally, when an application is about to be terminated (either by the user or the system) the application delegate’s applicationWillTerminate method is called.
Checking for Multitasking Support
Multitasking is only supported on the iPhone 3GS and later devices running iOS 4.0 or newer. In the case of devices where multitasking is not supported, applications are simply terminated rather than being placed in the background.
If you are developing an application that relies on multitasking it is recommended that defensive code be implemented to check for multitasking support so that application behavior can be modified to compensate for the missing functionality. This can be achieved using the following code fragment:
-(bool)multitaskingAvailable { UIDevice* device = [UIDevice currentDevice]; backgroundIsSupported = NO; if ([device respondsToSelector: @selector(isMultitaskingSupported)]) backgroundISSupported = device.multitaskingSupported; return backgroundIsSupported; }
When the above method is called it returns either YES or NO depending on whether or not multitasking is supported on the device.
Enabling Multitasking for an iOS Application
Multitasking support is disabled by default for all applications developed in Xcode. In situations where an application is required to enter background mode a configuration setting is required in the application’s Info.plist file. The simplest way to make this configuration change is to select the application target at the top of the project navigator panel, select the Capabilities tab and switch the Background Modes option from Off to On as illustrated in Figure 61-1:
Figure 61-1
Once selected, the appropriate setting will be added to the application’s Info.plist file to enable multitasking support.
Learn SwiftUI and take your iOS Development to the Next Level |
Supported Forms of Background Execution
So far we have looked primarily at the types of applications for which a suspended background state is acceptable to the user. Apple, however, recognizes nine categories in which application suspension would be detrimental to the user experience, these being audio, location updates, voice over IP (VOIP), Newsstand updates, external and Bluetooth accessory communication, background fetch and remote notifications.
The background execution modes supported by an application are configured in the application’s Info.plist file using the UIBackgroundModes key. The value for the key is actually an array allowing an application to register for more than one background execution mode. To select the background modes, simply enable the checkbox next to the required modes within the Background Modes section of the project Capabilities panel as outlined in Figure 61-1 above.
An Overview of Background Fetch
Background fetch must first be enabled in the background modes settings for the application via the Capabilities panel previously discussed. Once enabled, the background fetch interval must be set. By default this is set to UIApplicationBackgroundFetchIntervalNever which will result in no fetch operations being scheduled. To let iOS calculate optimal fetch operations, the application’s setMinimumBackgroundFetchInterval method may be called within the application delegate as follows:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. [[UIApplication sharedApplication] setMinimumBackgroundFetchInterval: UIApplicationBackgroundFetchIntervalMinimum]; return YES; }
Once background fetches have been suitably enabled and configured, the application’s performFetchWithCompletionHandler: delegate method will be called for each fetch. This method should also be implemented within the application delegate file for example,
-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { // Perform tasks to get latest content and update user interface completionHandler(UIBackgroundFetchResultNewData); }
When called, it is the responsibility of the method to obtain the latest content for the application (such as news articles in the case of a news app). Passed as an argument to the delegate method is the reference to a completion handler which must be called once the fetch is complete. When the handler is called, it must be passed as an argument a value indicating the success or otherwise of the fetch operation. In the example above, the completion handler is notified that new data was received. The method should also be implemented to handle situations where the fetch fails, or no new data was available. This can be achieved by using the UIBackgroundFetchResultNoData and UIBackgroundFetchResultFailed values.
If the application is not already running in the background when a fetch is scheduled to occur, it will be launched in the background by the operating system and the fetch delegate method called. To test this behavior, edit the scheme for the application by clicking on the current scheme in the Xcode toolbar and selecting the Edit Scheme… menu option as outlined in Figure 61-2:
Figure 61-2
Within the Edit Scene panel, select the Run/Debug option in the left hand panel followed by Options in the main panel, enable the check box next to Launch due to a background fetch and click on OK:
Figure 61-3
When the application is next run, it will launch in the background and the fetch delegate method will be called. Once the testing is complete, re-edit the scheme and turn off the background fetch toggle.
The second scenario to test involves situations where the application is already in the background when the fetch is triggered. To test this, run the application and place it into the background using the home button. Once in the background, select the Xcode Debug -> Simulate Background Fetch menu option.
An Overview of Remote Notifications
Remote Notifications allow applications to receive notifications from a remote server and process that notification in the background. When a notification for the application arrives, the application is woken up and passed the message so that it can act on it. Notifications are typically displayed to the user once they have been handled by the application, though the option is also provided to allow a notification to be silent so that only the application knows it has been received. This allows you, for example, to notify your application via a remote server that some form of new content or data is available for download. The application can then download that data and have it ready for the user next time they access the application.
With Remote notifications background mode enabled in the project capabilities panel, and the appropriate notification server set up and configured, the application’s didReceiveRemoteNotification: delegate method will be called when a notification arrives on the device for it. Once the notification has been handled, the completion handler passed to the delegate method then needs to be called.
An Overview of Local Notifications
Suspended applications and those running in one of the background execution modes do not, by definition, have access to the display of the iOS device. In recognition of the fact that background applications may still need to display alert messages to users, Apple introduced the Local Notifications feature in iOS 4. Unlike the Remote Notifications functionality, local notifications allow alerts to be triggered from within the local application without the need to rely on a remote server.
A local notification may be triggered at any time by an executing background application. Suspended applications must, however, schedule the notification to be delivered at a future time as part of the clean up process contained within the applicationDidEnterBackground method. A step-by-step example of how to schedule a local notification within an application entering suspended mode is covered in the chapter entitled Scheduling iOS 7 Local Notifications.
An Overview of Background Transfer Service
The background transfer service, also new in iOS 7, allows applications to perform large file upload and download operations in the background in a way that optimizes battery efficiency. Background transfer services are continued regardless of whether or not the application exits and will automatically resume in the event that the device is rebooted. The application will receive notifications via delegate methods when the download completes, or in the event that an error occurs. If the application exited before the transfer completes, it will be automatically restarted on completion. Download sessions are implemented using the NSURLSession API and using a process that is best described through the creation of an example application project, one of which will be created in the chapter entitled An iOS 7 Background Transfer Service Tutorial.
The Rules of Background Execution
Apple recommends that a number of rules be observed when running an application in background execution mode:
- Only perform the minimum tasks when the application is in background mode. For example, if the application is playing audio content, the application should only perform the tasks necessary to maintaining the audio stream. All other tasks should be placed on hold until the application is returned to the foreground.
- Do not perform updates to the user interface of the application. Since the application is in the background the user cannot see the user interface. There is nothing, therefore, to be gained (except for unnecessarily using CPU cycles and draining the battery) by continuing to update the UI.
- Do not perform OpenGL ES calls. Doing so will cause your application to be terminated.
- Always save the state and data information for the application when notification is received that it is entering the background. Even when suspended, an application may be terminated by the system in order to free up resources.
- Stop using shared resources such as the address book or calendar when the background notification is received to avoid termination.
- Attempt to release any memory used by the application that can safely be released without impacting the application’s subsequent return to the foreground. The more memory a suspended application is holding on to the more likely it is to be terminated should the system need to free up resources.
- Cancel Bonjour related services.
Summary
This chapter has provided a summary of the way in which multitasking functions on iOS 7 within the context of an application. The chapter has also looked at some of the tasks that can be performed when an application is in the background, such as receiving notifications, performing transfers of large files and fetching new content.
Learn SwiftUI and take your iOS Development to the Next Level |
Previous | Table of Contents | Next |
Integrating iAds into an iOS 7 App | An iOS 7 Background Transfer Service Tutorial |