当在后台时引起用户注意
通知是一种应用被挂起、或在后台运行、或没有运行的情况下引起用户注意的方式。应用可以使用本地通知来显示警告、播放声音、印章化应用的图标、或者三者的组合。例如,一个闹钟应用可以使用本地通知来播放闹钟声音并显示一个警告来关掉闹钟。当一个通知被传递给用户的时候,用户必须根据信息决定是否让应用回到前台。(如果应用已经运行在前台,本地通知只会安静的传递给应用而不会显示给用户。)
为了安排本地通知的传递,创建一个UILocalNotification类的实例,配置通知参数,并使用UIApplication类的方法来安排它。本地通知对象包含关于用来传递的通知类型(声音、警告、或者徽章)的信息以及发送它的时间(当合适时)。UIApplication类的方法为立刻或在安排的时间传递通知提供了选项。
代码清单3-2显示了一个使用用户设定的日期和时间安排一个单次警告的例子。这个例子只配置了一次警告,并在安排一个新的警告之前取消了之前的警告。(你自己的应用可以在任何时刻有不超过128个的本地通知,其中任何一个都可以配置为以指定间隔重复。)警告本身由一个警告框和一个声音文件组成;当警告触发时,如果应用在不运行或者在后台运行的时候,声音文件会播放。如果应用正处于活动状态,因此正在前台运行,作为替代,应用委托的application:didReceiveLocalNotification:方法被调用
代码清单3-2 安排警告通知
- (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。
理解你的应用何时在后台启动
支持后台执行的应用可以通过系统重启来处理传入的事件。如果应用由于除用户强退之外的原因而被终止,系统会在下面这些事件发生的时候重启应用:
- 对于位置应用:
- 系统接收到一个与应用所配置的传送标准匹配的位置更新。
- 设备进入或退出一个注册区域。(区域可以是地理区域或iBeacon区域。)
- 对于音频应用,音频框架需要应用来处理一些数据。(音频应用包括那些播放或使用麦克风的应用。)
- 对于蓝牙应用:
- 应用扮演从连接的外设获取数据的中心角色。
- 应用扮演从连接中心获取命令的外设角色。
- 对于后台下载应用:
- 应用的推送通知到达,它的通知内容包含值为1的content-available键。
- 系统在有机会的时刻唤醒应用来开始下载新内容。
- 对于使用NSURLSession类在后台下载内容的应用,所有与会话对象关联的任务都成功完成或接收到一个错误。
- Newsstand应用启动的下载任务完成。
在大多数情况下,系统会不在用户强退应用后重启应用。一个例外是位置应用,在iOS 8及更新的版本中,它能在用户强退之后被重启。然而在其它情况下,用户必须明确启动应用或在应用能被系统从后台自动启动之前重启设备。当设备启用密码保护时,系统在用户首次解锁设备之前无法从后台启动应用。
做一个负责任的后台应用
在使用系统资源和硬件时,前台应用总是优先于后台应用。运行在后台的应用需要为这种差异做好准备,并在它们运行在后台的时候调整其行为。具体来说,应用在进入到后台的时候应该遵循下面的指导:
- 不要从代码进行任何OpenGL ES的调用。当运行在后台的时候,你不能创建EAGLContext对象或者发出任何OpenGL ES绘图命令。使用这些调用会导致应用被立刻杀死。应用还必须确保任何之前提交的命令在进入后台之前都已完成。关于如何在进入或移出后台的时候处理OpenGL ES的信息,参见 OpenGL ES Programming Guide中的Implementing a Multitasking-aware OpenGL ES Application。
- 在被挂起前取消所有Bonjour相关的服务。当应用进入后台,并在被挂起前,它应该从Bonjour注销,并关闭任何与网络服务相关的socket监听。挂起的应用不能响应任何传入的服务请求。关闭这些服务保护它们在其事实上不可用的时候被显示为可用。如果你没有关闭Bonjour服务,系统会在应用被挂起的时候自动关闭这些服务。
- 在基于网络socket中为处理连接失败做好准备。系统会在应用被各种原因挂起的时候拆除socket连接。只要你的基于socket的代码为其他网络失败的类型做好了准备,例如信号丢失或者网络转换,则不会导致任何异常问题。当应用恢复时,如果在使用socket的时候遇到故障,值需要重新建立连键即可。
- 在进入后台之前保存应用的状态。在低内存条件下,后台应用可以被从内存清除以释放更多空间。挂起的应用首先会被清除,而且在被清除之前不会有任何通知。因此,应用应该利用iOS 6及更高版本的状态保存机制来保存它们的界面状态到磁盘。关于如何支持这个功能的信息,参见Preserving Your App’s Visual Appearance Across Launches。
- 在进入后台的时候移除不必要对象的强引用。如果应用维持一个占用大量内存的对象(特别是图片)的缓存,那就在进入后台的时候移除所有值像这些缓存的强引用。更多信息,参见Reduce Your Memory Footprint。
- 在被挂起之前停止使用共享系统资源。与共享系统资源,例如地址簿或日历数据库,进行交互的应用,应该在被挂起之前停止使用这些资源。这些资源总是优先提供给前台应用。当应用被挂起时,如果它被发现正在使用共享资源,应用会被杀死。
- 避免更新你的窗口和视图。因为当应用在后台的时候,它的窗口可视图不可见,所以你应该避免更新它们。只有在你获取应用快照之前需更更新窗口内容的情况下才可以例外。
- 响应连接或断开外部配件的通知。与外部配件连接的应用,系统会在应用进入后台的时候自动发送一个断开连接通知。该应用必须注册这个通知,以便用它来关闭当前的配件会话。当应用返回到前台的时候,一个匹配的连接通知会被发送,给应用一个机会来重新连接。更多处理配件连接和断开通知的信息,参见External Accessory Programming Topics。
- 当进入后台的时候清除活动警告的资源。为了在应用之间切换的时候保护内容,系统不会在应用进入后台的时候自动关闭操作表单(UIActionSheet)或警告视图(UIAlertView)。在进入后台之前,由你提供适当地清理行为。例如,你可能想通过编码的方式取消活动表单或者警告视图,或者保存足够的上下文信息以便稍后恢复视图(在应用程序被终止的情况下)。
- 在进入后台之前,删除视图上的敏感信息。当应用转换到后台,系统得到应用主窗口的一张快照,然后应用转换回到前台的时候快照会短暂显示。在从applicationDidEnterBackground:方法返回之前,你应该隐藏或者遮挡密码以及其它可能被快照捕获的敏感的个人信息。
- 在后台运行的时候尽可能少做事。给予后台应用的执行时间比器前台应用要受到更多的限制。在后台花费很多时间运行的应用可能会被系统限制或终止。
如果你正在后台执行一个音频应用,或者允许在后台运行的其他类型应用,应用可以照常的响应传入消息。换句话说,系统可能会在发生低内存警告的时候通知应用。在这种情况下系统需要终止应用来释放更多的内存,该应用会调用它的applicationWillTerminate:委托方法来执行退出前的最后任务。
选择不在后台执行
如果你不想让应用在后台执行,你可以通过将UIApplicationExitsOnSuspend键(值为YES)添加到在Info.plist 文件来明确的选择不进入后台。当应用选择不进入时,应用会在不运行、非活动、以及活动状态之间循环,而不会进入到后台或者挂起状态。当应用按下Home按钮退出应用的时候,applicationWillTerminate:方法会被调用,并且在应用终止并进入不运行状态之前,有大约5秒钟的时间来清理及退出。
强烈不推荐选择不进入后台执行,但是在某些特定情况下可能是首选。具体来说,如果为后台执行的编码增加了应用很大的复杂性,终止应用或许是一个更简便的方案。此外,如果你的应用消耗大量的内存并且无法轻松释放它,系统会迅速的杀死你的应用来为其他应用腾出空间。因此,选择终止,而不是切换到后台,可能会产生相同的结果,并节省开发的时间和精力。
更过关于能包含到Info.plist文件中的键的信息,参见Information Property List Key Reference。
(本节结束)