APP编程指南 (三) —— 应用程序的后台执行(一)

版本记录

版本号 时间
V1.0 2018.05.30

前言

我们在做一个APP时候需要注意哪些方面呢,接下来我们就看一下APP编程指南。里面有些可能大家在平时编程中都经历过,但是再系统的了解下也不是坏事。感兴趣的可以看上面写的几篇。
1. APP编程指南 (一) —— 基本概览(一)
2. APP编程指南 (二) —— 应用程序必须实现的行为(一)

Background Execution - 后台执行

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

大多数应用程序可以轻松移动到暂停状态,但也有合理的理由让应用程序继续在后台运行。远足应用可能需要随着时间的推移跟踪用户的位置,以便它可以显示重叠在远足地图上的该路线。音频应用可能需要继续在锁定屏幕上播放音乐。其他应用可能需要在后台下载内容,以便将内容呈现给用户的延迟最小化。当您发现有必要让您的应用程序保持在后台运行时,iOS可帮助您高效地完成此任务,并且不会耗尽系统资源或用户的电池电量。 iOS提供的技术分为三类:

  • 当应用程序移动到后台时,在前台开始短任务的应用程序可以要求时间来完成该任务。

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

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

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


Executing Finite-Length Tasks - 执行有限长度的任务

移动到后台的应用程序会尽快让自己进入静止状态,以便系统暂停它们。如果您的应用程序处于任务中间并需要一点额外时间才能完成该任务,则可以调用UIApplication对象的 beginBackgroundTaskWithName:expirationHandler:beginBackgroundTaskWithExpirationHandler:方法来请求一些额外的执行时间。调用其中任何一种方法都会暂时延迟您的应用程序的暂停,给它一点额外的时间来完成其工作。完成该工作后,您的应用程序必须调用endBackgroundTask:方法来让系统知道它已完成并可以暂停。

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

您无需等到应用程序移至后台以指定后台任务。更有用的设计是在开始任务之前调用beginBackgroundTaskWithName:expirationHandler:beginBackgroundTaskWithExpirationHandler:方法,并在完成后立即调用endBackgroundTask:方法。您甚至可以在前台执行应用程序时遵循此模式。

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

// Listing 3-1  Starting a background task at quit time

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    bgTask = [application beginBackgroundTaskWithName:@"MyTask" expirationHandler:^{
        // Clean up any unfinished task business by marking where you
        // stopped or ending the task outright.
        [application 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, preferably in chunks.
 
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    });
}

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


Downloading Content in the Background - 在后台下载内容

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

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

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

  • 使用NSURLSessionConfigurationbackgroundSessionConfigurationWithIdentifier:方法创建配置对象。

  • 将配置对象的sessionSendsLaunchEvents属性的值设置为YES。

  • 如果您的应用程序在位于前台时开始传输,则建议您还将配置对象的discretionary属性设置为YES。

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

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

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

当与后台会话相关的所有任务都完成后,系统重新启动已终止的应用程序(假设sessionSendsLaunchEvents属性设置为YES并且用户未强制退出应用程序)并调用应用程序委托的应用程序:application:handleEventsForBackgroundURLSession:completionHandler:方法。 (系统还可以重新启动应用程序以处理需要关注应用程序的身份验证挑战或其他与任务相关的事件。)在实现该委托方法时,使用提供的标识符创建一个新的NSURLSessionConfigurationNSURLSession对象,其配置与之前相同。系统将您的新会话对象重新连接到之前的任务,并将其状态报告给会话对象的代理。


Implementing Long-Running Tasks - 实施长期运行任务

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

  • 在后台播放可听内容的应用,例如音乐播放器应用
  • 在后台录制音频内容的应用程序
  • 随时向用户通知其位置的应用,例如导航应用
  • 支持网际协议语音(VoIP)的应用
  • 需要定期下载和处理新内容的应用程序
  • 从外部附件获得定期更新的应用程序

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

1. Declaring Your App’s Supported Background Tasks - 声明您的应用程序支持的后台任务

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

Table 3-1 Background modes for apps

Xcode background mode UIBackgroundModes value Description
Audio and AirPlay audio 该应用程序向用户播放可听内容或在后台录制音频。 (此内容包括使用AirPlay播放音频或视频内容。)。用户必须授权应用程序在第一次使用之前使用麦克风; 有关更多信息,请参阅 Supporting User Privacy
Location updates location 即使在后台运行时,该应用也会向用户通知其位置。
Voice over IP voip 该应用程序为用户提供了使用互联网连接拨打电话的功能。
Newsstand downloads newsstand-content 该应用程序是一个报亭应用程序,可在后台下载和处理杂志或报纸内容
External accessory communication external-accessory 该应用程序与需要通过外部附件框架定期传递更新的硬件附件配合使用。
Uses Bluetooth LE accessories bluetooth-central 该应用程序适用于需要通过核心蓝牙框架定期提供更新的蓝牙配件。
Acts as a Bluetooth LE accessory bluetooth-peripheral 该应用程序通过Core Bluetooth框架支持外设模式下的蓝牙通信。使用此模式需要用户授权; 有关更多信息,请参阅 Supporting User Privacy
Background fetch fetch 该应用程序定期从网络下载和处理少量内容。
Remote notifications remote-notification 该应用程序想要在推送通知到达时开始下载内容。 使用此通知可最大限度地减少显示与推送通知相关内容的延迟。

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

2. Tracking the User’s Location - 跟踪用户的位置

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

  • 重大变更的位置服务(推荐)
  • 仅前台位置服务
  • 后台定位服务

强烈建议对不需要高精度位置数据的应用程序进行重大更改的位置服务。有了这项服务,只有当用户的位置发生重大变化时才会生成位置更新;因此,它非常适合向用户提供非关键的位置相关信息的社交应用或应用。如果应用程序在发生更新时暂停,系统会在后台将其唤醒以处理更新。如果应用程序启动此服务,然后终止,系统会在新位置可用时自动重新启动应用程序。此服务在iOS 4及更高版本中可用,并且仅在包含蜂窝无线电的设备上可用。

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

您可以从Xcode项目的Capabilities选项卡的Background modes部分启用位置支持。 (您也可以通过在应用程序的Info.plist文件中包含具有location值的UIBackgroundModes键来启用此支持。)启用此模式不会阻止系统暂停应用程序,而它确实告知系统应该唤醒应用程序,每当有新的位置数据提供。因此,该key有效地让应用程序在后台运行,以在发生位置更新时处理它。

重要提示:我们鼓励您谨慎使用标准服务,或者改用重要的位置更改服务。 位置服务需要主动使用iOS设备的机载无线电硬件。 持续运行此硬件可能会消耗大量的电力。 如果您的应用不需要向用户提供精确和连续的位置信息,最好尽量减少位置服务的使用。

有关如何在您的应用中使用每种不同位置服务的信息,请参阅 Location and Maps Programming Guide

3. Playing and Recording Background Audio - 播放和录制后台音频

持续播放或录制音频的应用程序(即使应用程序在后台运行时)可以注册以在后台执行这些任务。您可以从Xcode项目的Capabilities选项卡的Background modes部分启用音频支持。 (您也可以通过在应用程序的Info.plist文件中包含带有audio值的UIBackgroundModes键来启用此支持。)在后台播放音频内容的应用程序必须播放可听内容而不是静音。

后台音频应用程序的典型示例包括:

  • 音乐播放器应用
  • 录音应用程序
  • 支持通过AirPlay播放音频或视频的应用程序
  • VoIP应用程序

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

您可以使用任何系统音频框架来处理后台音频内容,并且使用这些框架的过程不会改变。 (通过AirPlay播放视频,您可以使用Media PlayerAV Foundation框架呈现您的视频。)由于您的应用在播放媒体文件时未被暂停,因此当您的应用处于后台时,回调功能正常运行。不过,在你的回调中,你应该只做必要的工作来提供回放数据。例如,流式音频应用程序需要从其服务器下载音乐流数据并将当前音频采样推出用于回放。应用不应执行与播放无关的任何无关任务。

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

4. Implementing a VoIP App - 实现一个VoIP App

通过Voice over Internet Protocol (VoIP) app,用户可以使用互联网连接而不是设备的手机服务拨打电话。这样的应用程序需要与其关联的服务保持持久的网络连接,以便它可以接收来电和其他相关数据。系统不会一直保持VoIP应用程序的唤醒状态,而是允许它们暂停并提供监视其socket的功能。当检测到传入流量时,系统会唤醒VoIP应用程序并将其socket控制权交还给它。

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

  • 从Xcode项目的Capabilities选项卡的Background modes部分启用对IP语音的支持。 (您也可以通过在应用程序的Info.plist文件中包含带有voip值的UIBackgroundModes键来启用此支持。)

  • 为VoIP使用配置其中一个应用socket

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

  • 配置您的audio session以处理active使用的转换。

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

大多数VoIP应用程序还需要配置为后台音频应用程序,以在后台传送音频。因此,您应该将audiovoip值都包含在UIBackgroundModes项中。如果您不这样做,您的应用程序在后台播放时不能播放或录制音频。有关UIBackgroundModes键的更多信息,请参阅信Information Property List Key Reference

有关实施VoIP应用程序必须执行的步骤的具体信息,请参阅Tips for Developing a VoIP App

5. Fetching Small Amounts of Content Opportunistically - 适时提取少量内容

需要定期检查新内容的应用程序可以要求系统将其唤醒,以便他们可以启动对该内容的提取操作。要支持此模式,请在Xcode项目的Capabilities选项卡的Background模式部分中启用Background fetch选项。 (您也可以通过在应用程序的Info.plist文件中包含具有获取值的UIBackgroundModes项来启用此支持。)启用此模式并不能保证系统会随时为您的应用程序提供后台提取。系统必须在您的应用程序的需求和获取其他应用程序和系统本身的需求之间进行权衡。在评估这些信息后,系统会在有很好机会的情况下为应用程序提供时间。

当出现合适时机时,系统会唤醒或启动您的应用程序并调用应用程序代理application:performFetchWithCompletionHandler:方法。如果内容可用,请使用该方法检查新内容并启动下载操作。一旦完成下载新内容,您必须执行提供的完成处理程序块,并传递一个结果,指示内容是否可用。执行此块会告诉系统它可以将您的应用程序移回挂起状态并评估其用电量。快速下载少量内容并准确反映他们何时可以下载内容的应用程序比将需要很长时间下载内容的应用程序或声明内容可用但后来不下载任何东西的程序可能获得更多的执行时间。

下载任何内容时,建议您使用NSURLSession类来启动和管理您的下载。有关如何使用此类来管理上载和下载任务的信息,请参阅URL Loading System Programming Guide

6. Using Push Notifications to Initiate a Download - 使用推送通知启动下载

如果您的服务器在新内容可用于您的应用程序时向您的设备发送推送通知,则可以要求系统在后台运行您的应用程序,以便它可以立即开始下载新内容。此后台模式的目的是尽可能减少用户看到推送通知到应用程序能够显示相关内容的时间。应用程序通常在用户看到通知的大致同一时间醒来,但仍然会给您比您可能得到的更多时间。

要支持这种后台模式,请从Xcode项目中Capabilities选项卡的Background modes部分启用Remote notifications选项。 (您也可以通过在应用程序的Info.plist文件中包含带有remote-notification值的UIBackgroundModes键来启用此支持。)

对于触发下载操作的推送通知,通知的有效内容必须包含content-available这个key并将其值设置为1。当该key存在时,系统在后台唤醒应用程序(或将其启动到后台)以及调用应用程序委托的应用程序:application:didReceiveRemoteNotification:fetchCompletionHandler:方法。您实施该方法应下载相关内容并将其集成到您的应用中。

下载任何内容时,建议您使用NSURLSession类来启动和管理您的下载。有关如何使用此类来管理上载和下载任务的信息,请参阅URL Loading System Programming Guide

7. Downloading Newsstand Content in the Background - 在后台下载Newsstand内容

一个下载新杂志或报纸问题的Newsstand应用程序可以注册在后台执行这些下载。您可以从Xcode项目中Capabilities选项卡的Background modes部分启用对Newsstand下载的支持。 (您也可以通过在应用程序的Info.plist文件中包含带有Newsstand-content值的UIBackgroundModes键来启用此支持。)当此键存在时,系统将启动您的应用程序(如果它尚未运行),以便它可以开始下载新问题。

当您使用Newsstand Kit框架来启动下载时,系统将处理您的应用程序的下载过程。即使您的应用程序被暂停或终止,系统也会继续下载文件。下载操作完成后,系统会将文件传输到您的应用沙箱并通知您的应用。如果应用程序未运行,则此通知会将其唤醒并使其有机会处理新下载的文件。如果在下载过程中出现错误,您的应用程序同样会被唤醒以处理它们。

有关如何使用Newsstand Kit框架下载内容的信息,请参阅Newsstand Kit Framework Reference

8. Communicating with an External Accessory - 与外部配件通信

如果附件在应用暂停时发布更新,那么与外部附件配合使用的应用可能会要求将其唤醒。这种支持对于定期传输数据的某些类型的附件很重要,例如心率监测器。您可以从Xcode项目的Capabilities选项卡的Background modes部分启用对外部配件通信的支持。 (您也可以通过在应用程序的Info.plist文件中包含具有external-accessory值的UIBackgroundModes项来启用此支持。)启用此模式时, external accessory框架不会关闭与附件的活动会话。 (在iOS 4及更早版本中,这些会话会在应用程序暂停时自动关闭。)当新数据从附件到达时,框架会唤醒您的应用程序,以便它可以处理该数据。系统还会唤醒应用程序以处理附件连接和断开通知。

任何支持附件更新后台处理的应用程序都必须遵循以下几条基本准则:

  • 应用程序必须提供一个界面,允许用户启动和停止附件更新事件的传送。该界面应该随后打开或关闭附件会话。

  • 被唤醒后,该应用程序大约需要10秒来处理数据。理想情况下,它应该尽可能快地处理数据,并允许自己再次被暂停。但是,如果需要更多时间,应用程序可以使用beginBackgroundTaskWithExpirationHandler:方法来请求更多时间,但它应该在绝对必要时才这样做。

9. Communicating with a Bluetooth Accessory - 与蓝牙配件通信

如果应用程序暂停时外围设备提供更新,那么与蓝牙外围设备配合使用的应用程序可能会要求唤醒。这种支持对于定期提供数据的Bluetooth-LE附件非常重要,例如蓝牙心率带。您可以从Xcode项目的Capabilities选项卡的Background modes部分启用对使用蓝牙配件的支持。 (您也可以通过在您的应用程序的Info.plist文件中包含带有bluetooth-central值的UIBackgroundModes项来启用此支持。)启用此模式后,Core Bluetooth框架会为相应外设保持打开任何活动会话。另外,来自外设的新数据会导致系统唤醒应用程序,以便处理数据。系统还会唤醒应用程序以处理附件连接和断开连接通知。

在iOS 6中,应用程序还可以使用蓝牙配件以外设模式运行。要充当蓝牙配件,您必须从Xcode项目的Capabilities选项卡的Background modes部分启用对该模式的支持。 (您也可以通过在应用程序的Info.plist文件中包含具有bluetooth-peripheral值的UIBackgroundModes键来启用此支持。)启用此模式后,Core Bluetooth框架可以在后台短暂唤醒应用程序,以便它可以处理附件 - 相关请求。唤醒这些事件的应用程序应该处理它们并尽快返回,以便应用程序可以再次暂停。

任何支持蓝牙数据后台处理的应用都必须基于会话,并遵循一些基本准则:

  • 应用程序必须提供一个界面,允许用户启动和停止蓝牙事件的传送。该界面应该适当地打开或关闭会话。

  • 被唤醒后,该应用程序大约需要10秒来处理数据。理想情况下,它应该尽可能快地处理数据,并允许自己再次被暂停。但是,如果需要更多时间,应用程序可以使用beginBackgroundTaskWithExpirationHandler:方法来请求更多时间,但它应该在绝对必要时才这样做。


Getting the User’s Attention While in the Background - 在后台获取用户注意力

通知是应用被暂停,处于后台或未运行状态,可以吸引用户的注意力的一种方式。应用可以使用本地通知显示提醒,播放声音,标记应用图标或三者的组合。例如,闹钟应用可能会使用本地通知来播放闹钟声音,并显示警报以禁用闹钟。当通知发送给用户时,用户必须决定信息是否允许应用程序回到前台。 (如果应用程序已经在前台运行,则本地通知悄悄地传递到应用程序而不传递给用户。)

要计划本地通知的传递,请创建UILocalNotification类的实例,配置通知参数,并使用UIApplication类的方法对其进行计划。本地通知对象包含有关要发送的通知类型(声音,警报或徽章)的信息以及发送通知的时间(适用时)。UIApplication类的方法提供了立即或在计划时间发送通知的选项。

Listing 3-2显示了一个使用用户设置的日期和时间来计划单个警报的示例。此示例一次只配置一个警报,并在安排新警报之前取消之前的警报。 (您自己的应用程序在任何给定时间不能有超过128个本地通知活动,其中任何一个可以配置为以指定的时间间隔重复。)警报本身包含一个警告框和一个声音文件,当警报发生时如果应用程序没有运行或处于后台就会播放该声音文件。如果应用程序处于活动状态并因此在前台运行,则会调用应用程序委托的application:didReceiveLocalNotification:方法。

// Listing 3-2  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];
    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];
    }
}

用于本地通知的声音文件与用于推送通知的声音文件具有相同的要求。 自定义声音文件必须位于应用程序主包中,并支持以下格式之一:Linear PCM,MA4,μ-Law或a-Law。 您还可以指定UILocalNotificationDefaultSoundName常量来播放设备的默认警报声音。 发送通知并播放声音时,系统也会在支持震动的设备上触发振动。

您可以使用UIApplication类的方法取消预定的通知或获取通知列表。 有关这些方法的更多信息,请参阅 UIApplication Class Reference。 有关配置本地通知的其他信息,请参阅Local and Remote Notification Programming Guide


Understanding When Your App Gets Launched into the Background - 了解您的应用程序何时启动到后台

支持后台执行的应用程序可能会被系统重新启动以处理传入的事件。如果应用除了因用户强制退出以外的原因被终止,系统会在发生以下事件之一时启动应用:

  • 对于位置应用:
    • 系统会收到符合应用配置的传输条件的位置更新。
    • 设备进入或退出注册区域。 (地区可以是地理区域或iBeacon地区。)
  • 对于音频应用程序,音频框架需要应用程序来处理一些数据。 (音频应用程序包括播放音频或使用麦克风的应用程序。)
  • 对于蓝牙应用:
    • 以中心角色行事的应用程序会从连接的外围设备接收数据。
    • 以外设角色行事的应用程序会接收来自连接中央的命令。
  • 为后台下载应用程序:
    • 推送通知到达应用程序,通知的有效负载包含值为1的content-available的键。
    • 系统在合适时机启动应用程序以开始下载新内容。
    • 对于使用NSURLSession类在后台下载内容的应用程序,与该会话对象关联的所有任务要么成功完成,要么收到错误。
    • Newsstand应用发起的下载完成。

在大多数情况下,系统在用户强制退出后不会重新启动应用程序。位置应用程序是一个例外,iOS 8和更高版本在用户强制退出后重新启动。但在其他情况下,用户必须明确启动应用程序或重新reboot设备,然后系统才能将应用程序自动启动到后台。在设备上启用密码保护后,系统不会在用户解锁设备之前在后台启动应用程序。


Being a Responsible Background App - 成为负责任的后台应用程序

前台应用程序在使用系统资源和硬件时总是优先于后台应用程序。在后台运行的应用程序需要为这种差异做好准备,并在后台运行时调整其行为。具体来说,移动到后台的应用程序应遵循以下准则:

  • Do not make any OpenGL ES calls from your code - 不要通过代码进行任何OpenGL ES调用

  • Cancel any Bonjour-related services before being suspended - 在被暂停前取消所有Bonjour相关服务

    • 当您的应用移动到后台,在暂停之前,它应该从Bonjour注销并关闭与任何网络服务关联的socket的监听。无论如何,暂停的应用程序无法响应传入的服务请求。关闭这些服务可防止它们在实际上不可用时显示为可用。如果您自己没有关闭Bonjour服务,系统会在您的应用程序暂停时自动关闭这些服务。
  • Be prepared to handle connection failures in your network-based sockets - 准备好处理基于网络的套接字中的连接失败

    • 由于许多原因,系统可能会在您的应用程序暂停时拆除套接字连接。只要您的基于套接字的代码准备好用于其他类型的网络故障(如丢失信号或网络转换),就不会导致任何异常问题。当您的应用程序恢复时,如果在使用socket时遇到故障,则只需重新建立连接即可。
  • Save your app state before moving to the background - 在移至后台之前保存您的应用状态

    • 在低内存条件下,后台应用程序可能会从内存中清除以释放空间。首先清除已暂停的应用程序,并在清除应用程序之前不会通知应用程序。因此,应用程序应该利用iOS 6及更高版本中的状态保存机制将其接口状态保存到磁盘。有关如何支持此功能的信息,请参阅Preserving Your App’s Visual Appearance Across Launches
  • Remove strong references to unneeded objects when moving to the background - 移动到后台时删除对不需要的对象的强引用

    • 如果您的应用程序维护对象(特别是图像)的大容量内存缓存,请在移至后台时移除对这些缓存的所有强引用。有关更多信息,请参阅Reduce Your Memory Footprint
  • Stop using shared system resources before being suspended - 在被暂停之前停止使用共享系统资源

    • 与共享系统资源(如通讯簿或日历数据库)交互的应用程序应在停用之前停止使用这些资源。这些资源的优先级总是应该给与进入前台应用程序。当您的应用程序被暂停时,如果发现它使用共享资源,该应用程序将被终止。
  • Avoid updating your windows and views - 避免更新你的窗口和视图

    • 由于当您的应用处于后台时,您的应用的窗口和视图不可见,因此应该避免更新它们。例外情况是您需要在拍摄应用程序快照之前更新窗口内容。
  • Respond to connect and disconnect notifications for external accessories - 响应连接并断开外部附件的通知

    • 对于与外部附件进行通信的应用程序,系统会在应用程序移动到后台时自动发送断开连接通知。该应用程序必须注册此通知并使用它来关闭当前的配件会话。当应用程序移回到前台时,相应的会发送连接通知,为应用程序提供重新连接的机会。有关处理配件连接和断开通知的更多信息,请参阅External Accessory Programming Topics
  • Clean up resources for active alerts when moving to the background - 移动到后台时清理活动警报的资源

    • 为了在应用程序之间切换时保留上下文,当您的应用程序移动到背景时,系统不会自动消除操作表(UIActionSheet)或警报视图(UIAlertView)。在移至后台之前,您需要提供适当的清理行为。例如,您可能想要以编程方式取消操作表或警报视图,或者保存足够的上下文信息以在稍后恢复视图(在应用程序终止的情况下)。
  • Remove sensitive information from views before moving to the background - 在移至后台之前,从视图中移除敏感信息

    • 当应用程序转换到后台时,系统会拍摄应用程序主窗口的快照,然后在将应用程序切换回前台时,该窗口会短暂显示。在从applicationDidEnterBackground:方法返回之前,您应该隐藏或遮掩可能作为快照一部分捕获的密码和其他敏感个人信息。
  • Do minimal work while running in the background - 在后台运行时做最少的工作

    • 给后台应用程序的执行时间比给予前台应用程序的时间要少很多。系统花费太多时间执行的应用程序可能会被系统限制或终止。

如果您正在实现后台音频应用或允许在后台运行的任何其他类型的应用,则您的应用会以通常的方式响应传入的消息。换句话说,系统可能会在他们发生时,以低内存警告的方式通知给您。在系统需要终止应用程序以释放更多内存的情况下,应用程序会在退出之前调用其委托的applicationWillTerminate:方法执行任何最终任务。


Opting Out of Background Execution - 选择退出后台执行

如果您不希望应用程序在后台运行,则可以通过向应用程序的Info.plist文件添加UIApplicationExitsOnSuspend键(值为YES)来明确退出后台。当一个应用程序退出时,它会在未运行状态,不活动状态和活动状态之间循环,并且永远不会进入后台或暂停状态。当用户按Home按钮退出应用程序时,应用程序代理的applicationWillTerminate:方法被调用,应用程序有大约5秒的时间清理并退出,然后终止并移回非运行状态。

不鼓励退出后台执行,但在某些情况下可能是首选。特别是,如果为后台执行编码增加了应用程序的复杂性,终止应用程序可能是一个更简单的解决方案。此外,如果您的应用程序消耗大量内存,并且无法轻松释放任何内容,则系统可能会迅速杀死您的应用程序,以便为其他应用程序腾出空间。因此,选择终止,而不是切换到后台,可能会产生相同的结果,并节省您的开发时间和精力。

有关可以包含在应用的Info.plist文件中的key的更多信息,请参阅Information Property List Key Reference

后记

本篇主要介绍了后台执行相关的内容,感兴趣的给个赞或者关注~~~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容