适用于iOS的应用程序编程指南(三)

后台执行

当用户没有主动使用您的应用程序时,系统将其移动到后台状态。对于许多应用程序,后台状态只是暂停应用程序的一个短暂停留。暂停应用程序是提高电池寿命的一种方式,它还允许系统将重要的系统资源投入到引起用户关注的新前台应用程序中。

大多数应用程序可以轻松变换到暂停状态,但是还有合理原因让应用程序在后台继续运行。远足应用程序可能希望跟踪用户的位置,以便它可以在远足地图上显示该课程。音频应用程序可能需要在锁定屏幕上继续播放音乐。其他应用程序可能希望在后台下载内容,以便最大限度地减少将内容呈现给用户的延迟。当您发现有必要使您的应用程序在后台运行时,iOS可以有效地执行,而不会耗尽系统资源或用户的电量。iOS提供的技术分为三类:

当应用程序切换到后台时,应用程序可以在前台启动一个简短的任务。

在前台启动下载的应用程序可以将这些下载的管理权交给系统,从而允许在下载过程中暂停或终止该应用。

需要在后台运行以支持特定类型任务的应用程序可以声明对一个或多个后台执行模式的支持。

始终尽量避免做任何后台工作,除非这样做改善了整体用户体验。由于用户启动了不同的应用程序,或者因为用户锁定了设备,而且目前还没有使用它,应用程序可能会移动到后台。在这两种情况下,用户都在指示您的应用程序现在不需要做任何有意义的工作。继续在这样的条件下运行,只会耗尽设备的电池,并可能导致用户强制退出您的应用程序。所以要注意你在后台做的工作,避免这种情况。

执行有限长度任务

移动到后台的应用程序预计将尽可能快地进入静态状态,以便系统可以暂停。如果您的应用程序在任务的中间,并且需要一些额外的时间才能完成该任务,那么可以调用UIApplication对象的beginBackgroundTaskWithName:expirationHandler:或beginBackgroundTaskWithExpirationHandler:方法来请求一些额外的执行时间。调用这些方法之一会暂时延迟您的应用程序的暂停,给它一些额外的时间来完成它的工作。完成该工作后,您的应用程序必须调用endBackgroundTask:方法让系统知道它已经完成并可以被挂起。

每次调用beginBackgroundTaskWithName:expirationHandler:或beginBackgroundTaskWithExpirationHandler:方法生成一个与相应任务关联的唯一标记。当您的应用程序完成任务时,它必须使用相应的令牌调用endBackgroundTask:方法,以使系统知道该任务已完成。如果没有为后台任务调用endBackgroundTask:方法将导致您的应用程序终止。如果您在启动任务时提供了一个到期处理程序,系统将调用该处理程序给你最后一次机会结束任务并避免直接终止任务。

您不需要等到您的应用程序移动到后台来指定后台任务。一个更有用的设计是在开始任务之前调用beginBackgroundTaskWithName:expirationHandler:或beginBackgroundTaskWithExpirationHandler:方法,一旦完成就调用endBackgroundTask:方法。您甚至可以在应用程序在前台执行时遵循此模式。

清单3-1显示了当应用程序转换到后台时如何启动长时间运行的任务。在此示例中,启动后台任务的请求包括一个到期处理程序,以防任务耗时太长。然后将任务本身提交给一个调度队列进行异步执行,以便applicationDidEnterBackground:方法可以正常返回。使用blocks简化了维护对任何重要变量(例如后台任务标识符)的引用所需的代码。bgTask变量是存储指向当前后台任务标识符的指针的类的成员变量,并在此方法使用之前初始化它。

清单3-1退出时启动后台任务

-(void)applicationDidEnterBackground:(UIApplication *)application

{

bgTask = [applicationbeginBackgroundTaskWithName:@"MyTask" expirationHandler:^{

// Clean up anyunfinished task business by marking where you

// stopped orending the task outright.

[applicationendBackgroundTask:bgTask];

bgTask =UIBackgroundTaskInvalid;

}];

// Start the long-running taskand return immediately.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{

// Do the workassociated with the task, preferably in chunks.

[applicationendBackgroundTask:bgTask];

bgTask =UIBackgroundTaskInvalid;

});

}

注意:始终在启动任务时提供一个到期处理程序,但是如果您想知道应用程序运行多少时间,请获取UIApplication的backgroundTimeRemaining属性的值。

在您自己的过期处理程序中,您可以包括关闭任务所需的其他代码。但是,您所包含的任何代码都不能太长时间执行,因为在调用过期处理程序时,您的应用程序已经非常接近其时间限制。因此,只执行最少的清除状态信息并结束任务。

在后台下载内容

当下载文件时,应用程序应使用NSURLSession对象来开始下载,以便系统可以控制下载过程,以防应用程序被暂停或终止。当您配置NSURLSession对象进行后台传输时,系统会在单独的进程中管理这些传输,并以常规方式将状态报告回您的应用程序。如果您的应用程序在传输正在进行时终止,系统会在后台继续传输,并在传输完成或一个或多个任务需要您的应用程序注意时启动应用程序(如appropriate)。

要支持后台传输,您必须适当地配置您的NSURLSession对象。要配置会话,必须先创建一个NSURLSessionConfiguration对象,并将几个属性设置为适当的值。然后,在创建会话时,将该配置对象传递给NSURLSession的适当初始化方法。

创建支持后台下载的配置对象的过程如下:

1 使用NSURLSessionConfiguration的backgroundSessionConfigurationWithIdentifier:方法创建配置对象。

2 将配置对象的sessionSendLaunchEvents属性的值设置为YES。

3 如果您的应用程序在前台进行转移,建议您将配置对象的自由属性设置为YES。

4 根据需要配置配置对象的任何其他属性。

5 使用配置对象创建您的NSURLSession对象。

一旦配置,您的NSURLSession对象无缝地在适当的时候将上传和下载任务交给系统。如果任务在您的应用程序仍在运行(在前台或后台)中完成,则会话对象以通常的方式通知其代理。如果任务尚未完成,并且系统终止您的应用程序,系统将自动继续在后台管理任务。如果用户终止您的应用程序,系统将取消任何挂起的任务。

当与后台会话相关联的所有任务完成时,系统重新启动终止的应用程序(假定sessionSendLaunchEvents属性设置为YES,用户没有强制退出该应用程序),并调用应用程序委托应用程序:handleEventsForBackgroundURLSession:completionHandler: 方法。 (系统还可以重新启动应用程序来处理需要您的应用程序注意的身份验证检验或其他与任务相关的事件。)在执行该委托方法时,请使用提供的标识符创建新的NSURLSessionConfiguration和NSURLSession对象,其配置与之前相同。系统会将您的新会话对象重新连接到先前的任务,并将其状态报告给会话对象的委托。

实施长时间运行的任务

对于需要执行更多执行时间的任务,您必须请求特定的权限才能在后台运行它们,而不会被挂起。在iOS中,只有特定的应用类型才能在后台运行:

在背景中向用户播放音频内容的应用程序,如音乐播放器应用程序

在后台记录音频内容的应用程序

随时让用户了解其位置的应用程序,例如导航应用程序

支持互联网语音协议(VoIP)的应用程序

需要定期下载和处理新内容的应用程序

从外部配件接收定期更新的应用程序

实施这些服务的应用程序必须声明其支持的服务,并使用系统框架来实现这些服务的相关方面。声明服务允许系统知道您使用哪些服务,但在某些情况下,系统框架实际上阻止您的应用程序被暂停。

声明您的应用程序支持的后台任务

某些类型的后台执行的支持必须由使用它们的应用程序提前声明。在Xcode 5及更高版本中,您可以从项目设置的“功能”选项卡中声明应用程序支持的后台模式。启用后台模式选项将UIBackgroundModes键添加到应用程序的Info.plist文件中。选择一个或多个复选框将相应的背景模式值添加到该键。表3-1列出了您可以指定的背景模式以及Xcode在应用程序的Info.plist文件中分配给UIBackgroundModes键的值。

表3-1应用程序的背景模式

Xcode背景模式

UIBackgroundMode值

描述


音频和AirPlay

音频

该应用程序播放声音内容给用户或在后台记录音频。 (此内容包括使用AirPlay流式传输音频或视频内容。)

在第一次使用之前,用户必须授权应用程序使用麦克风;有关详细信息,请参阅支持用户隐私。Supporting User Privacy


位置更新

位置

该应用程序即使在后台运行时也会将用户通知他们的位置。


IP语音通话

VOIP

该应用程序提供用户使用Internet连接拨打电话的功能。


报摊下载

报摊内容

该应用程序是一个报亭应用程序,可在后台下载和处理杂志或报纸内容。


外部附件通讯

外部附件

该应用程序与需要通过外部附件框架定期提供更新的硬件配件配合使用。


使用蓝牙LE配件

蓝牙中心

该应用程序与蓝牙配件配合使用,需要通过核心蓝牙框架定期提供更新。


充当蓝牙LE附件

蓝牙外设

该应用程序通过核心蓝牙框架支持外设模式下的蓝牙通信。

使用此模式需要用户授权;有关详细信息,请参阅支持用户隐私。Supporting User Privacy.


后台抓取

该应用程序定期从网络下载和处理少量内容。


远程通知

远程通知

该应用程序想要在推送通知到达时开始下载内容。使用此通知来最小化显示与推送通知相关的内容的延迟。


以上每种模式都可让系统知道您的应用程序应该在适当的时间唤醒或启动,以响应相关事件。例如,开始播放音乐然后移动到背景的应用程序仍然需要执行时间来填充音频输出缓冲器。启用音频模式会告诉系统框架,他们应该继续以适当的时间间隔对应用进行必要的回调。如果应用程序没有选择此模式,则当应用程序移动到背景时,应用程序播放或记录的任何音频都会停止。

跟踪用户的位置

有几种方法可以在后台跟踪用户的位置,其中大部分实际上不需要您的应用在后台连续运行:

重大变更位置服务(推荐)

前景专属定位服务

背景定位服务

强烈建议对不需要高精度位置数据的应用进行重大改变位置服务。使用此服务,只有当用户位置发生明显变化时才会生成位置更新;因此,它是为用户提供非关键的位置相关信息的社交应用程序或应用程序的理想选择。如果应用程序在发生更新时被暂停,系统将在后台唤醒以处理更新。如果应用程序启动此服务,然后终止,则系统会在新位置可用时自动重新启动应用程序。此服务可在iOS4及更高版本中使用,并且仅在包含蜂窝网广播的设备上可用。

仅前台和后台位置服务都使用标准位置的Core Location服务来检索位置数据。唯一的区别是,如果应用程序被暂停,则前台专用位置服务停止传递更新,如果应用程序不支持其他后台服务或任务,则可能会发生更新。前景专用位置服务适用于在前台只需要位置数据的应用程序。

您可以从Xcode项目的“功能”选项卡的“后台”模式部分启用位置支持。 (您也可以通过在应用程序的Info.plist文件中包含UIBackgroundModes键和位置值来启用此支持。)启用此模式不会阻止系统挂起应用程序,但它会告诉系统它应该唤醒每当有新的位置数据传递时,应用程序。因此,该密钥有效地使应用程序在后台运行,以便在发生时处理位置更新。

重要提示:建议您谨慎使用标准服务或改用重要的位置更改服务。位置服务需要积极使用iOS设备的板载无线电硬件。连续运行这个硬件可以消耗大量的电量。如果您的应用程序不需要向用户提供精确且连续的位置信息,最好尽量减少使用位置服务。

有关如何在应用程序中使用每个不同位置服务的信息,请参阅位置和地图编程指南。Location and Maps Programming Guide

播放和录制背景音频

连续播放或记录音频的应用程序(即使应用程序在后台运行)也可以注册以在后台执行这些任务。您可以从Xcode项目中的“功能”选项卡的“后台”模式部分启用音频支持。(您也可以通过在应用的Info.plist文件中包含UIBackgroundModes键和音频值来启用此支持。)在后台播放音频内容的应用程序必须播放声音内容,而不是静音。

背景音频应用程序的典型示例包括:

音乐播放器应用程序

录音应用程式

支持通过AirPlay播放音频或视频的应用程序

VoIP应用程序

当UIBackgroundModes键包含音频值时,系统的媒体框架会自动阻止相应的应用程序在移动到后台时被暂停。只要播放音频或视频内容或录制音频内容,该应用程序将继续在后台运行。但是,如果录制或播放停止,系统将暂停该应用程序。

您可以使用任何系统音频框架来处理背景音频内容,并且使用这些框架的过程不变。 (对于通过AirPlay进行视频播放,您可以使用媒体播放器或AVFoundation框架来呈现您的视频。)由于您的应用程序在播放媒体文件时未被暂停,所以回调在您的应用程序处于后台时正常运行。但是,在回调中,您只需要提供数据进行播放所需的工作。例如,流式音频应用程序将需要从其服务器下载音乐流数据,并将当前音频样本推出以进行播放。应用程序不应执行与播放无关的任何无关的任务。

由于多个应用程序可能支持音频,系统会确定在任何给定时间允许哪个应用程序播放或录制音频。前台应用程序始终具有音频操作的优先级。允许多个后台应用程序播放音频,这样的确定是基于每个应用程序的音频会话对象的配置。您应该始终配置您的应用程序的音频会话对象,并与系统框架仔细配合,以处理中断和其他类型的音频相关通知。有关如何配置音频会话对象以进行后台执行的信息,请参阅音频会话编程指南。Audio Session Programming Guide

实施VoIP应用

互联网语音协议(VoIP)应用允许用户使用因特网连接而不是设备的蜂窝服务进行电话呼叫。这样的应用程序需要维护与其相关服务的持续网络连接,以便它可以接收来电和其他相关数据。而不是一直保持VoIP应用程序清醒,系统允许它们被暂停,并提供监控他们的套接字的设施。当检测到传入流量时,系统唤醒VoIP应用程序,并将其套接字的控制权返回给它。

要配置VoIP应用程序,您必须执行以下操作:

1 在Xcode项目的“功能”选项卡的“后台模式”部分启用对IP语音的支持。 (您还可以通过在应用程序的Info.plist文件中包含带有voip值的UIBackgroundModes键来启用此支持。)

2 配置一个应用程序的套接字用于VoIP使用。

3 在移动到后台之前,调用setKeepAliveTimeout:handler:方法来安装要定期执行的处理程序。您的应用程序可以使用此处理程序来维护其服务连接。

4 配置您的音频会话以处理到和使用的转换。

在UIBackgroundModes键中包含voip值可以让系统知道它应该允许应用程序根据需要在后台运行来管理其网络套接字。系统启动后立即重新启动具有该密钥的应用程序,以确保VoIP服务始终可用。

大多数VoIP应用程序还需要配置为背景音频应用程序,以便在后台传送音频。因此,您应该将音频和voip值都包含在UIBackgroundModes键中。如果您不这样做,您的应用程序在后台无法播放或录制音频。有关UIBackgroundModes键的更多信息,请参阅信息属性列表键参考。Information Property List Key Reference

有关实现VoIP应用程序必须采取的步骤的具体信息,请参阅开发VoIP应用程序的提示。Tips for Developing a VoIP App.

你可能感兴趣的:(适用于iOS的应用程序编程指南(三))