http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/BackgroundExecution/BackgroundExecution.html
If you do not want your application to remain in the background when it is quit, you can explicitly opt out of the background execution model by adding the
Opting out of background execution may be preferable for certain types of applications. Specifically, if coding for the background may require adding significant complexity to your application, terminating the application may be a simpler solution. Also, if your application consumes a large amount of memory, the system might need to terminate your application quickly anyway to make room for other applications. Thus, opting to terminate, instead of switch to the background, might yield the same results and save you development time and effort.
Support for some types of background execution must be declared in advance by the application that uses them. An application declares this support by including the
In addition to the preceding keys, iOS provides two other ways to do work in the background:
For applications that require more precise location data at regular intervals, such as navigation applications, you need to declare the application as a continuous background application. This option is available for applications that truly need it, but it is the least desirable option because it increases power usage considerably.
For information about how to use each of the location services in your application, see Location Awareness Programming Guide.
When the
You can use any of the system audio frameworks to initiate the playback of background audio, and the process for using those frameworks is unchanged. (For video playback over AirPlay, you must use the Media Player framework to present your video.) Because your application is not suspended while playing media files, callbacks operate normally while your application is in the background. Your application should limit itself to doing only the work necessary to provide data for playback while in the background. For example, a streaming audio application would download any new data from its server and push the current audio samples out for playback. You should not perform any extraneous tasks that are unrelated to playing the content.
Because more than one application may support audio, the system limits which applications can play audio at any given time. The foreground application always has permission to play audio. In addition, one or more background applications may also be allowed to play some audio content depending on the configuration of their audio session object. Applications should always configure their audio session object appropriately and work carefully with the system frameworks to handle interruptions and other types of audio-related notifications. For information on how to configure your application’s audio session properly for background execution, see Audio Session Programming Guide.
To configure a VoIP application, you must do the following:
Most VoIP applications also need to be configured as background audio applications to deliver audio while in the background. Therefore, you should include both the
You need to tag only the socket you use for communicating with your VoIP service. This is the socket you use to receive incoming calls or other data relevant to maintaining your VoIP service connection. Upon receipt of incoming data, the handler for this socket needs to decide what to do. For an incoming call, you likely want to post a local notification to alert the user to the call. For other noncritical data, though, you might just process the data quietly and allow the system to put your application back into the suspended state.
In iOS, most sockets are managed using streams or other high-level constructs. To configure a socket for VoIP usage, the only thing you have to do beyond the normal configuration is add a special key that tags the interface as being associated with a VoIP service. Table 4-1 lists the stream interfaces and the configuration for each.
Because VoIP applications need to stay running in order to receive incoming calls, the system automatically relaunches the application if it exits with a nonzero exit code. (This type of exit could happen in cases where there is memory pressure and your application is terminated as a result.) However, terminating the application also releases all of its sockets, including the one used to maintain the VoIP service connection. Therefore, when the application is launched, it always needs to create its sockets from scratch.
For more information about configuring Cocoa stream objects, see Stream Programming Guide. For information about using URL requests, see URL Loading System Programming Guide. And for information about configuring streams using the CFNetwork interfaces, see CFNetwork Programming Guide.
Your keep-alive handler executes in the background and should return as quickly as possible. Handlers are given a maximum of 30 seconds to perform any needed tasks and return. If a handler has not returned after 30 seconds, the system terminates the application.
When installing your handler, specify the largest timeout value that is practical for your application’s needs. The minimum allowable interval for running your handler is 600 seconds and attempting to install a handler with a smaller timeout value will fail. Although the system promises to call your handler block before the timeout value expires, it does not guarantee the exact call time. To improve battery life, the system typically groups the execution of your handler with other periodic system tasks, thereby processing all tasks in one quick burst. As a result, your handler code must be prepared to run earlier than the actual timeout period you specified.
For information about how to configure and manage an audio session for a VoIP application, see Audio Session Programming Guide.
You can use task completion to ensure that important but potentially long-running operations do not end abruptly when the user leaves the application. For example, you might use this technique to save user data to disk or finish downloading an important file from a network server. There are a couple of design patterns you can use to initiate such tasks:
An application can have any number of tasks running at the same time. Each time you start a task, the
Listing 4-2 shows how to start a long-running task when your application transitions to the background. In this example, the request to start a background task includes an expiration handler just in case the task takes too long. The task itself is then submitted to a dispatch queue for asynchronous execution so that the
In your own expiration handlers, you can include additional code needed to close out your task. However, any code you include must not take too long to execute. By the time your expiration handler is called, your application is already very close to its time limit. For this reason, perform only minimal cleanup of your state information and end the task.
Listing 4-3 shows an example that schedules a single alarm using a date and time that is set by the user. This example configures only one alarm at a time and cancels the previous alarm before scheduling a new one. (Your own applications can have no more than 128 local notifications active at any given time, any of which can be configured to repeat at a specified interval.) The alarm itself consists of an alert box and a sound file that is played if the application is not running or is in the background when the alarm fires. If the application is active and therefore running in the foreground, the application delegate’s
Sound files used with local notifications have the same requirements as those used for push notifications. Custom sound files must be located inside your application’s main bundle and support one of the following formats: Linear PCM, MA4, ยต-Law, or a-Law. You can also specify the sound name
If you do not want your application to remain in the background when it is quit, you can explicitly opt out of the background execution model by adding the
UIApplicationExitsOnSuspend key to your application’s Info.plist file and setting its value to YES. When an application opts out, it cycles between the not running, inactive, and active states and never enters the background or suspended states. When the user taps the Home button to quit the application, the applicationWillTerminate: method of the application delegate is called and the application has approximately five seconds to clean up and exit before it is terminated and moved back to the not running state.Opting out of background execution may be preferable for certain types of applications. Specifically, if coding for the background may require adding significant complexity to your application, terminating the application may be a simpler solution. Also, if your application consumes a large amount of memory, the system might need to terminate your application quickly anyway to make room for other applications. Thus, opting to terminate, instead of switch to the background, might yield the same results and save you development time and effort.
Support for some types of background execution must be declared in advance by the application that uses them. An application declares this support by including the
UIBackgroundModes key in its Info.plist file. Its value is an array that contains one or more strings with the following values:audio. The application plays audible content to the user while in the background. (This includes streaming audio or video content using AirPlay.)location. The application keeps users informed of their location, even while running in the background.voip. The application provides the ability for the user to make phone calls using an Internet connection.
audio key tells the system frameworks that they should continue playing and make the necessary callbacks to the application at appropriate intervals. If the application does not include this key, any audio being played by the application stops when the application moves to the background. In addition to the preceding keys, iOS provides two other ways to do work in the background:
- Task completion—Applications can ask the system for extra time to complete a given task.
- Local notifications—Applications can schedule local notifications to be delivered at a predetermined time.
Implementing Long-Running Background Tasks
Applications can request permission to run in the background in order to manage specific services for the user. Such applications do not run continuously but are woken up by the system frameworks at appropriate times to perform work related to those services.Tracking the User’s Location
There are several ways to track the user’s location in the background, some of which do not actually involve running regularly in the background:- Applications can register for significant location changes. (Recommended) The significant-change location service offers a low-power way to receive location data and is highly recommended for applications that do not need high-precision location data. With this service, location updates are generated only when the user’s location changes significantly; thus, it is ideal for social applications or applications that provide the user with noncritical, location-relevant information. If the application is suspended when an update occurs, the system wakes it up in the background to handle the update. If the application starts this service and is then terminated, the system relaunches the application automatically when a new location becomes available. This service is available in iOS 4 and later, only on devices that contain a cellular radio.
- Applications can continue to use the standard location services. Although not intended for running indefinitely in the background, the standard location services are available in all versions of iOS and provide the usual updates while the application is running, including while running in the background. However, updates stop as soon as the application is suspended or terminated, and new location updates do not cause the application to be woken up or relaunched. This type of service is appropriate when location data is used primarily when the application is in the foreground.
- An application can declare itself as needing continuous background location updates. An application that needs regular location updates, both in the foreground and background, should add the
UIBackgroundModeskey to itsInfo.plistfile and set the value of this key to an array containing thelocationstring. This option is intended for applications that provide specific services, such as navigation services, that involve keeping the user informed of his or her location at all times. The presence of the key in the application’sInfo.plistfile tells the system that it should allow the application to run as needed in the background.
For applications that require more precise location data at regular intervals, such as navigation applications, you need to declare the application as a continuous background application. This option is available for applications that truly need it, but it is the least desirable option because it increases power usage considerably.
For information about how to use each of the location services in your application, see Location Awareness Programming Guide.
Playing Background Audio
Applications that play audio can include theUIBackgroundModes key (with the value audio) in their Info.plist file to register as a background-audio application. This key is intended for use by applications that provide audible content to the user while in the background, such as music-player or streaming-audio applications. Applications that support audio or video playback over AirPlay should also include this key so that they continue streaming their content while in the background. When the
audio value is present, the system’s media frameworks automatically prevent your application from being suspended when it moves to the background. As long as it is playing audio or video content, the application continues to run in the background to support that content. However, if the application stops playing that audio or video, the system suspends it. Similarly, if the application does not include the appropriate key in its Info.plist file, the application becomes eligible for suspension immediately upon entering the background.You can use any of the system audio frameworks to initiate the playback of background audio, and the process for using those frameworks is unchanged. (For video playback over AirPlay, you must use the Media Player framework to present your video.) Because your application is not suspended while playing media files, callbacks operate normally while your application is in the background. Your application should limit itself to doing only the work necessary to provide data for playback while in the background. For example, a streaming audio application would download any new data from its server and push the current audio samples out for playback. You should not perform any extraneous tasks that are unrelated to playing the content.
Because more than one application may support audio, the system limits which applications can play audio at any given time. The foreground application always has permission to play audio. In addition, one or more background applications may also be allowed to play some audio content depending on the configuration of their audio session object. Applications should always configure their audio session object appropriately and work carefully with the system frameworks to handle interruptions and other types of audio-related notifications. For information on how to configure your application’s audio session properly for background execution, see Audio Session Programming Guide.
Implementing a VoIP Application
A Voice over Internet Protocol (VoIP) application allows the user to make phone calls using an Internet connection instead of the device’s cellular service. Such an application needs to maintain a persistent network connection to its associated service so that it can receive incoming calls and other relevant data. Rather than keep VoIP applications awake all the time, the system allows them to be suspended and provides facilities for monitoring their sockets for them. When incoming traffic is detected, the system wakes up the VoIP application and returns control of its sockets to it.To configure a VoIP application, you must do the following:
- Add the
UIBackgroundModeskey to your application’sInfo.plistfile. Set the value of this key to an array that includes thevoipstring. - Configure one of the application’s sockets for VoIP usage.
- Before moving to the background, call the
setKeepAliveTimeout:handler:method to install a handler to be executed periodically. Your application can use this handler to maintain its service connection. - Configure your audio session to handle transitions to and from active use.
voip value in the UIBackgroundModes key lets the system know that it should allow the application to run in the background as needed to manage its network sockets. An application with this key is also relaunched in the background immediately after system boot to ensure that the VoIP services are always available. Most VoIP applications also need to be configured as background audio applications to deliver audio while in the background. Therefore, you should include both the
audio and voip values to the UIBackgroundModes key. If you do not do this, your application cannot play audio while it is in the background. For more information about the UIBackgroundModes key, see Information Property List Key Reference. Configuring Sockets for VoIP Usage
In order for your application to maintain a persistent connection while it is in the background, you must tag your application’s main communication socket specifically for VoIP usage. Tagging this socket tells the system that it should take over management of the socket when your application is suspended. The handoff itself is totally transparent to your application. And when new data arrives on the socket, the system wakes up the application and returns control of the socket so that the application can process the incoming data.You need to tag only the socket you use for communicating with your VoIP service. This is the socket you use to receive incoming calls or other data relevant to maintaining your VoIP service connection. Upon receipt of incoming data, the handler for this socket needs to decide what to do. For an incoming call, you likely want to post a local notification to alert the user to the call. For other noncritical data, though, you might just process the data quietly and allow the system to put your application back into the suspended state.
In iOS, most sockets are managed using streams or other high-level constructs. To configure a socket for VoIP usage, the only thing you have to do beyond the normal configuration is add a special key that tags the interface as being associated with a VoIP service. Table 4-1 lists the stream interfaces and the configuration for each.
| Interface | Configuration |
|---|---|
NSInputStream and NSOutputStream | For Cocoa streams, use the setProperty:forKey: method to add the NSStreamNetworkServiceType property to the stream. The value of this property should be set to NSStreamNetworkServiceTypeVoIP. |
NSURLRequest | When using the URL loading system, use the setNetworkServiceType: method of your NSMutableURLRequest object to set the network service type of the request. The service type should be set to NSURLNetworkServiceTypeVoIP. |
CFReadStreamRef and CFWriteStreamRef | For Core Foundation streams, use the CFReadStreamSetProperty or CFWriteStreamSetProperty function to add the kCFStreamNetworkServiceType property to the stream. The value for this property should be set to kCFStreamNetworkServiceTypeVoIP. |
For more information about configuring Cocoa stream objects, see Stream Programming Guide. For information about using URL requests, see URL Loading System Programming Guide. And for information about configuring streams using the CFNetwork interfaces, see CFNetwork Programming Guide.
Installing a Keep-Alive Handler
To prevent the loss of its connection, a VoIP application typically needs to wake up periodically and check in with its server. To facilitate this behavior, iOS lets you install a special handler using thesetKeepAliveTimeout:handler: method of UIApplication. You typically install this handler in the applicationDidEnterBackground: method of your application delegate. Once installed, the system calls your handler at least once before the timeout interval expires, waking up your application as needed to do so.Your keep-alive handler executes in the background and should return as quickly as possible. Handlers are given a maximum of 30 seconds to perform any needed tasks and return. If a handler has not returned after 30 seconds, the system terminates the application.
When installing your handler, specify the largest timeout value that is practical for your application’s needs. The minimum allowable interval for running your handler is 600 seconds and attempting to install a handler with a smaller timeout value will fail. Although the system promises to call your handler block before the timeout value expires, it does not guarantee the exact call time. To improve battery life, the system typically groups the execution of your handler with other periodic system tasks, thereby processing all tasks in one quick burst. As a result, your handler code must be prepared to run earlier than the actual timeout period you specified.
Configuring Your Application’s Audio Session
As with any background audio application, the audio session for a VoIP application must be configured properly to ensure the application works smoothly with other audio-based applications. Because audio playback and recording for a VoIP application are not used all the time, it is especially important that you create and configure your application’s audio session object only when it is needed. For example, you would create it to notify the user of an incoming call or while the user was actually on a call. As soon as the call ends, you would then release the audio session and give other audio applications the opportunity to play their audio.For information about how to configure and manage an audio session for a VoIP application, see Audio Session Programming Guide.
Completing a Finite-Length Task in the Background
Any time before it is suspended, an application can call thebeginBackgroundTaskWithExpirationHandler: method to ask the system for extra time to complete some long-running task in the background. If the request is granted, and if the application goes into the background while the task is in progress, the system lets the application run for an additional amount of time instead of suspending it. (The backgroundTimeRemaining property of the UIApplication object contains the amount of time the application has to run.) You can use task completion to ensure that important but potentially long-running operations do not end abruptly when the user leaves the application. For example, you might use this technique to save user data to disk or finish downloading an important file from a network server. There are a couple of design patterns you can use to initiate such tasks:
- Wrap any long-running critical tasks with
beginBackgroundTaskWithExpirationHandler:andendBackgroundTask:calls. This protects those tasks in situations where your application is suddenly moved to the background. - Wait for your application delegate’s
applicationDidEnterBackground:method to be called and start one or more tasks then.
beginBackgroundTaskWithExpirationHandler: method must be balanced with a corresponding call to the endBackgroundTask: method. The endBackgroundTask: method lets the system know that the task is complete and that the application can now be suspended. Because applications are given only a limited amount of time to finish background tasks, you must call this method before time expires or the system will terminate your application. To avoid termination, you can also provide an expiration handler when starting a task and call the endBackgroundTask: method from there. (You can also check the value in the backgroundTimeRemaining property of the application object to see how much time is left.) An application can have any number of tasks running at the same time. Each time you start a task, the
beginBackgroundTaskWithExpirationHandler: method returns a unique identifier for the task. You must pass this same identifier to the endBackgroundTask: method when it comes time to end the task. Listing 4-2 shows how to start a long-running task when your application transitions to the background. In this example, the request to start a background task includes an expiration handler just in case the task takes too long. The task itself is then submitted to a dispatch queue for asynchronous execution so that the
applicationDidEnterBackground: method can return normally. The use of blocks simplifies the code needed to maintain references to any important variables, such as the background task identifier. The bgTask variable is a member variable of the class that stores a pointer to the current background task identifier.Listing 4-2 Starting a background task at quit time
- (void)applicationDidEnterBackground:(UIApplication *)application |
{ |
UIApplication* app = [UIApplication sharedApplication]; |
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ |
[app endBackgroundTask:bgTask]; |
bgTask = UIBackgroundTaskInvalid; |
}]; |
// Start the long-running task and return immediately. |
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ |
// Do the work associated with the task. |
[app endBackgroundTask:bgTask]; |
bgTask = UIBackgroundTaskInvalid; |
}); |
} |
Scheduling the Delivery of Local Notifications
TheUILocalNotification class in UIKit provides a way to schedule the delivery of local notifications. Unlike push notifications, which require setting up a remote server, local notifications are scheduled by your application and executed on the current device. You can use this capability to achieve the following behaviors:- A time-based application can ask the system to post an alert at a specific time in the future. For example, an alarm clock application would use this alert to implement alarms.
- An application running in the background can post a local notification to get the user’s attention.
UILocalNotification class, configure it, and schedule it using the methods of the UIApplication class. The local notification object contains information about the type of notification to deliver (sound, alert, or badge) and the time (when applicable) at which to deliver it. The methods of the UIApplication class provide options for delivering notifications immediately or at the scheduled time. Listing 4-3 shows an example that schedules a single alarm using a date and time that is set by the user. This example configures only one alarm at a time and cancels the previous alarm before scheduling a new one. (Your own applications can have no more than 128 local notifications active at any given time, any of which can be configured to repeat at a specified interval.) The alarm itself consists of an alert box and a sound file that is played if the application is not running or is in the background when the alarm fires. If the application is active and therefore running in the foreground, the application delegate’s
application:didReceiveLocalNotification: method is called instead. Listing 4-3 Scheduling an alarm notification
- (void)scheduleAlarmForDate:(NSDate*)theDate |
{ |
UIApplication* app = [UIApplication sharedApplication]; |
NSArray* oldNotifications = [app scheduledLocalNotifications]; |
// Clear out the old notification before scheduling a new one. |
if ([oldNotifications count] > 0) |
[app cancelAllLocalNotifications]; |
// Create a new notification. |
UILocalNotification* alarm = [[[UILocalNotification alloc] init] autorelease]; |
if (alarm) |
{ |
alarm.fireDate = theDate; |
alarm.timeZone = [NSTimeZone defaultTimeZone]; |
alarm.repeatInterval = 0; |
alarm.soundName = @"alarmsound.caf"; |
alarm.alertBody = @"Time to wake up!"; |
[app scheduleLocalNotification:alarm]; |
} |
} |
default to play the default alert sound for the device. When the notification is sent and the sound is played, the system also triggers a vibration on devices that support it.
No comments:
Post a Comment