[后台]在iOS后台执行

大多数应用程序进入后台状态不久后转入暂停状态。在这种状态下,应用程序不执行任何代码,并有可能在任意时候从内存中删除。应用程序提供特定的服务,用户可以请求后台执行时间,以提供这些服务。

判断是否支持多线程

UIDevice* device = [UIDevice currentDevice];

BOOL backgroundSupported = NO;

if ([device respondsToSelector:@selector(isMultitaskingSupported)])

backgroundSupported = device.multitaskingSupported;

 

声明你需要的后台任务

Info.plist中添加UIBackgroundModes键值,它包含一个或多个string的值,包括

audio:在后台提供声音播放功能,包括音频流和播放视频时的声音

location:在后台可以保持用户的位置信息

voip:在后台使用VOIP功能

前面的每个value让系统知道你的应用程序应该在适当的时候被唤醒。例如,一个应用程序,开始播放音乐,然后移动到后台仍然需要执行时间,以填补音频输出缓冲区。添加audio键用来告诉系统框架,需要继续播放音频,并且可以在合适的时间间隔下回调应用程序;如果应用程序不包括此项,任何音频播放在移到后台后将停止运行。

除了添加键值的方法,IOS还提供了两种途径使应用程序在后台工作:

Task completion—应用程序可以向系统申请额外的时间去完成给定的任务

Local notifications—应用程序可以预先安排时间执行local notifications 传递

 

实现长时间的后台任务

应用程序可以请求在后台运行以实现特殊的服务。这些应用程序并不连续的运行,但是会被系统框架在合适的时间唤醒,以实现这些服务

1、  追踪用户位置:略

2、  在后台播放音频:

添加UIBackgroundModesaudio值,注册后台音频应用。这个值使得应用程序可以在后台使用可听的背景,如音乐播放或者音频流应用。对于支持音频和视频功能的应用程序也可以添加该值以保证可以继续持续的运行流。

audio值设置后,当你的应用程序进入后台后,系统的多媒体框架会自动阻止它被挂断,但是,如果应用程序停止播放音频或者视频,系统将挂断应用程序

当你的应用程序在后台时,你可以执行任意的系统音频框架去初始化后台音频。你的应用程序在后台时应该限制自身,使其执行与工作相关的代码,不能执行任何与播放内容无关的任务

由于有多个应用程序支持音频,前台的应用程序始终允许播放音频,后台的应用程序也被允许播放一些音频内容,这取决于audio session object的设置。应用程序应该始终设置它们的audio session object,并小心的处理其他类型的音频相关notifications和中断。详见audio session programming guide

 

3、  实现VOIP应用:

VOIP程序需要稳定的网络去连接和它相关的服务,这样它才能接到来电和其他相关的数据。系统允许VOIP程序被挂断并提供组件去监听它们的sockets,而不是在任意时候都处于唤醒状态。设置VOIP应用程序如下:

A、 添加UIBackgroundModes中的VOIP键值

B、 VOIP设置一个应用程序socket

C、 在移出后台之前,调用setKeepAliveTimeout:handler:方法去建立一个定期执行的handler,你的应用程序可以运行这个handler来保持服务的连接。

D、 设置你的audio session去处理这种切换

 

释义:

A、 大多数VOIP应用需要设置后台audio 应用去传递音频,因此你应该设置audio voip两个键值。

B、 为了使应用程序在后台时保持稳定的连接,你必须tag你的主通讯socket专门应用于VOIPtagging这个socket来告诉系统,它必须在你的应用程序中断时接管这个socket。这个切换本身对于你的应用程序时透明的,当新的数据到达socket的时候,系统会唤醒应用程序,并将socket的控制权返回给应用程序,这样应用程序就可以处理新来的数据。

你只需要tag用于voip服务的socket,这个socket用来接收来电或者其他相关的数据来保持你的VOIP服务的连接。根据收到的信息,这个socket要决定下一步的动作。比如一个来电,你会想弹出一个本地的通知来告知用户;对于其他不是那么关键的数据,你可能会想悄悄的处理这些数据并让系统将应用程序重新中断。

IOS中,sockets是用流或者更高级的结构,设置一个VOIPsocket,你只需要在通常的设置中添加一个特殊的key来标明这个接口是用于连接VOIP服务的,下表列出了流的接口和设置:

设置流接口用于voip

接口

设置

NSInputStream 

NSOutputStream

对于 Cocoa streams, 使用setProperty:forKey: 方法添加

NSStreamNetworkServiceType 属性给stream. 改属性的值设为NSStreamNetworkServiceTypeVoIP.

NSURLRequest

对于 URL loading system, 使用setNetworkServiceType:

method of your NSMutableURLRequest object to set the network service

type of the request. The service type should be set to

NSURLNetworkServiceTypeVoIP.

CFReadStreamRef

CFWriteStreamRef

For Core Foundation streams, use the CFReadStreamSetProperty or

CFWriteStreamSetProperty function to add the kCFStreamNetwork-

ServiceType property to the stream. The value for this property should be

set to kCFStreamNetworkServiceTypeVoIP.

(注意:当设置socket的时候,你需要在你的主信号通道中设置合适的service type key。当设置声道时,不需要设置这个key

 

由于,VOIP应用程序需要一直运行以确保收到来电,所以如果程序通过一个非零的exit code退出,系统将自动重启这个应用程序(这种退出方式可以发生在内存压力大时终止程序运行)。尽管如此,中断应用程序会release所有的sockets,包括那个用于连接voip 服务的socket。因此,当程序运行时,它需要一直从头创建socket

 

C、 为了防止断连,voip程序需要定期被唤醒去检查它的服务。为了容易实现这个行为,IOS通过使用(UIApplication setKeepAliveTimeout:handler:)方法建立一个特殊的句柄。你可以在applicationDidEnterBackground方法中建立该句柄。一旦建立,系统至少会在超时之前调用该句柄一次,来唤醒你的应用程序。

这个keep-alive handler在后台执行,必须尽快的返回参数,它有最多30秒的时间来执行所需的任务,如果这段时间内句柄没有返回,那么系统将终止应用程序。

当你建立了handler之后,确定应用程序所需的最大超时。系统保证会在最大超时之前调用handler,但是这个时间是不确定的,所以你的handler必须在你申明的超时之前做好执行程序的准备。

D、设置audio session,详见Audio Session Programming Guide.

 

在后台完成有限长度的任务

在被终止之前的任意时间,应用程序会调用beginBackgroundTaskWithExpirationHandler:方法让系统给出额外的时间来完成一些需要在后台长时间执行的任务。(UIApplicationbackgroundTimeRemaining属性包含程序运行的总时间)

可以使用task completion去保证那些比较重要但是需要长时间运行的程序不会由于用户切入后台而突然关闭。比如,你可以用这项功能来将用户的信息保存到disk上或者从网络下载一个重要的文件。有两种方式来初始化这样的任务:

1.       将长时间运行的重要任务用beginBackgroundTaskWithExpirationHandler:和endBackgroundTask:包装。这样就在程序突然切入后台的时候保护了这些任务不被中断。

2.       当你的应用程序委托applicationDidEnterBackground:方法被调用时再启动任务

 

1中的两个方法必须是一一对应的,endBackgroundTask:方法告诉系统任务已经完成,程序在此时可以被终止。由于应用程序只有有限的时间去完成后台任务,你必须在超时或系统将要终止这个程序之前调用这个方法。为了避免被终止,你也可以在一个任务开始的时候提供一个expiration handlerendBackgroundTask:方法。(可以查看backgroundTimeRemaining属性来确定还剩多少时间)。

一个程序可以同时提供多个任务,每当你启动一个任务的时候,beginBackgroundTaskWithExpirationHandler:方法将返回一个独一无二的handler去识别这个任务。你必须在endBackgroundTask:方法中传递相同的handler来终止该任务。

 

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;

});

}

上述例子中,bgTask变量是一个类的成员变量,存储着指向该后台任务标示的指针。

expriation handler中,可以添加关闭任务所需的代码。尽管如此,加入的代码不能执行太长的时间,当expriation handler被调用的时候,该程序已经非常接近被关闭,所以只有极短的时间来清除状态信息并终止任务。

 

安排Local Notification的传递

UILocalNotification类提供了一种方法来传递local notifications。和push notifications需要设置remote server不同,local notifications 在程序中安排并在当前的设备上执行。满足如下条件可以使用该能力:

1.       一个基于时间的程序,可以在将来特定的时间让程序post 一个alert,比如闹钟

2.       一个在后台运行的程序,post 一个local notification去引起用户的注意

 

为了安排local notification 的传递,需要创建一个UILocalNotification的实例,并设置它,使用UIApplication类方法来安排它。Local notification对象包含了所要传递的类型(soundalert,或者badge)和时间何时呈现) UIApplication类方法提供选项去确定是立即传递还是在指定的时间传递。

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];

}

}

 

( 可以最多包含 128   local notifications active at any given time, any of which can be configured to repeat at a specified interval.) 如果在调用该 notification 的时候,程序已经处于前台,那么 application didReceiveLocalNotification :方法将取而代之。

原文

Executing Code in the Background

Most applications that enter the background state are moved to the suspended state shortly thereafter. While in this state, the application does not execute any code and may be removed from memory at any time. Applications that provide specific services to the user can request background execution time in order to provide those services.

Important: Most application developers do not need to read this chapter. This chapter does not address the basic multitasking support that all applications should adopt. It addresses only the steps needed to support executing code while the application is in the background state. For information about how to support basic multitasking in your applications, see “Multitasking.”

 

Applications linked against iOS SDK 4 and later are automatically assumed to support basic multitasking and to implement the appropriate methods to handle transitions to the background state.

Determining Whether Multitasking Support Is Available

The ability to execute code in the background is not supported on all iOS-based devices. Even devices running iOS 4 or later may not have the hardware to support multitasking. In those cases, the system reverts to the previously defined behavior for handling applications. Specifically, when an application quits, it is terminated and purged from memory.

Even applications built specifically for iOS 4 should be prepared to handle situations where multitasking is not available. If the presence or absence of multitasking changes the way your application behaves, it can use themultitaskingSupported property of the UIDevice class to determine whether the feature is available. Of course, if your application supports versions of the system earlier than iOS 4, you should always check the availability of this property before accessing it, as shown in Listing 4-1.

Listing 4-1  Checking for background support in earlier versions of iOS

UIDevice* device = [UIDevice currentDevice];
BOOL backgroundSupported = NO;
if ([device respondsToSelector:@selector(isMultitaskingSupported)])
   backgroundSupported = device.multitaskingSupported;

Declaring the Background Tasks You Support

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.

Each of the preceding values lets the system know that your application should be woken up at appropriate times to respond to relevant events. For example, an application that begins playing music and then moves to the background still needs execution time to fill the audio output buffers. Including the 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.

For more information about how to initiate background tasks from your code, see “Implementing Long-Running Background Tasks.”

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 UIBackgroundModes key to itsInfo.plist file and set the value of this key to an array containing the location string. 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’s Info.plist file tells the system that it should allow the application to run as needed in the background.

You are encouraged to use the significant location change service or use the standard services sparingly. Location services require the active use of an iOS device’s onboard radio hardware. Running this hardware continuously can consume a significant amount of power. If your application does not need to provide precise and continuous location information to the user, it is best to use those services that minimize power consumption. Chief among these low-power services is the significant location change service introduced in iOS 4. This service provides periodic location updates and can even wake up a background application, or relaunch a terminated application, to deliver them.

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 the UIBackgroundModes 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

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:

  1. Add the UIBackgroundModes key to your application’s Info.plist file. Set the value of this key to an array that includes the voip string.

  2. Configure one of the application’s sockets for VoIP usage.

  3. 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.

  4. Configure your audio session to handle transitions to and from active use.

Including the 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.

Table 4-1    Configuring stream interfaces for VoIP usage

Interface

Configuration

NSInputStream andNSOutputStream

For Cocoa streams, use the setProperty:forKey: method to add the NSStreamNetworkServiceType property to the stream. The value of this property should be set toNSStreamNetworkServiceTypeVoIP.

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 andCFWriteStreamRef

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.

Note: When configuring your sockets, you need to configure only your main signaling channel with the appropriate service type key. You do not need to include this key when configuring your voice channels.

 

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.

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 the setKeepAliveTimeout: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 the beginBackgroundTaskWithExpirationHandler: 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 theUIApplication 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: and endBackgroundTask: 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.

All calls to the 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;
    });
}

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.

Scheduling the Delivery of Local Notifications

The UILocalNotification 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.

To schedule the delivery of a local notification, create an instance of the 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];
    }
}

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 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.

You can cancel scheduled notifications or get a list of notifications using the methods of the UIApplication class. For more information about these methods, see UIApplication Class Reference. For additional information about configuring local notifications, see Local and Push Notification Programming Guide.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值