本地通知和推送通知的基本目的是让应用程序能够通知其用户某些事情——例如一个消息或者约会即将到达——同时,应用程序不需要在前台运行。二者的不同在于:

  • 本地通知由由应用程序计划,并同一设备上的iOS发出 ;
  • 推送通知,又叫远程通知,由远程服务器上的程序(提供者)发至APNs,再由APNs把消息推送至设备上的某个程序。
    推送通知在iOS和Mac OS X 10.7(Lion)以上版本有效。

本节描述本地通知和推送通知的一般概念并解释它们之间的不同。

提示:有关iOS推送通知的使用知道,参考“使用推送通知”(iOS Human Interface Guidelines) 。


推送通知和本地通知使用同样的界面

从用户的角度,推送通知和本地通知看起来是一样的。因为它们的目的都是一样的:通知某个应用程序的用户——可能该程序未处于当前任务中——有一些用户感兴趣的事情发生了。

让我们假设,你正在用iPhone打电话、上网或者听歌。但你的iPhone上安装了一个棋类游戏,你想和一个异地的朋友下棋,你下了先手,然后退出客户端,转而去收取邮件。此时,你的朋友回了一手,游戏的提供者(provider)知道了这步棋,发现你的客户端已经不再连接,于是发送了一个推送通知给APNs。很快,你的手机——准确地说是手机上的操作系统——通过WiFi或者蜂窝网络收到了这个通知。由于你的游戏客户端当前未运行在前台,iOS显示一个图1-1的告警消息,包含了应用程序名、一个简单文本消息、两个按钮:关闭、显示。右边的按钮叫做action按钮,它默认显示标题为“显示”。可以在程序中订制action按钮标题,或者使用用户指定的语言国际化按钮的标题和消息文本。

图 1-1一个告警通知

点击打开链接

如果你点击显示按钮,会启动这个棋类游戏,连接提供者,下载新的数据,调整棋盘界面,显示出你朋友刚下的这步棋。(按close按钮消除通知)

MacOS X 提示:目前,在Mac OS X上的推送通知只有一种:在未运行的应用程序的图标上显示徽标。也就是说,只有未运行的应用程序的Dock图标能显示徽标。如果没有把图标放到Dock上,系统会插入一个图标到Dock上以便能显示徽标(当程序退出后又会移除它)。对于正在运行的应用程序,则会检查通知的payload(载体)是否又其它类型的通知(告警和声音),然后处理它们。

让我们来看看有着另一种不同情况。有一种程序,它维护了一个to-do列表,列表中的每一项都有一个日期、时间,每个项目都需要完成。用户需要在相应日期到达之前让应用程序以某种周期提醒他。因此,应用程序需要针对这些日期和时间来计划本地通知。这次我们选择用一个指定的徽章数(1)作为通知。在约定的时间点,iOS在程序图标的右上角显示徽章数。如图1-2。

对于本地通知和推送通知,徽章数可以表示任何事情,比如即将来临的日历事件、要下载的文件数目、或者未读邮件(但已经下载)数目。用户看到徽章并点击应用程序图标——或者在Mac OS X中点击Dock面板上的图标——应用程序会启动,显示to-do列表或其他。

图 1-2带有徽章数的应用程序图标(iOS)

点击打开链接

在iOS中,可以和告警消息或徽章一起,指定一个声音文件。该声音文件应该播放一个短促、清晰的声音。iOS在显示告警或者徽章时,会播放声音以提醒用户。告警窗口可以只用一个按钮。稍后的例子里,action按钮被取消,如图1-3。这样,用户只能进行取消告警通知操作。

图 1-3没有action按钮的告警通知

点击打开链接

无论程序是否在运行,操作系统都会把本地通知发送到应用程序。如果程序在运行,本地通知不会显示告警窗口、徽章或者声音提醒,哪怕(iOS中)设备屏幕被锁住。但应用程序委托仍然会收到该通知并直接处理。(参考“Scheduling, Registering, and Handling Notifications”)

iPhone/iPad/iPod用户能够配置设备或者某个程序是否接收推送通知。也可以有选择地让应用程序接收或拒绝接收某种推送通知类型(比如, 徽章,提醒, 声音)。这是通过“设置”程序的“通知”中进行的。UIKit框架提供了判断这些选项的编程接口。

本地通知

本地通知(仅在iOS中有效)适用于基于时间的程序,包括简单的日历程序或者to-dolist类型的应用程序。那些在有限周期内运行的由iOS许可的后台程序也能够接收到本地通知。例如,依赖于服务器消息或数据的应用程序,能够在后台运行并查询服务器最新的数据;如果有消息要显示或者有更新需要下载,它们立即会显示一个本地通知以通知用户。

一个本地通知是一个UILocalNotification对象,它有3个常见属性:

A local notificationis an instance of UILocalNotificationwith three general kinds of properties:

  • Scheduled Time 必须指定一个日期时间,操作系统在这个时间发送通知;也叫做fire date。可以为这个fire date限定一个时区,这样当用户在旅行中系统能够重新调整fire date。还可以让系统用某种时间周期(周、月等等)来发送本地通知。
  • Notification type 类别包括提醒、action按钮标题、徽章数、声音。
  • Custom data 本地通知还可以包含用户的自定义数据。

“Scheduling Local Notifications”描述了这些属性的编码细节。一旦应用程序创建了一个本地通知对象,就可以让操作系统按计划发送或者立即发送。

每个应用程序都只能发近(新)的64个本地通知。超过该限制的通知将被操作系统自动放弃。重复出现的通知会被认为是一个通知。

推送通知

一个iOS或者Mac OS X应用程序通常只会是一个C/S架构的应用程序的一部分。客户端安装在设备或PC上,而服务端则向它的众多客户端提供数据(即“提供者”一词)。一个客户端有时会连接“提供者”下载它所需要的数据。Email和社区网络应用是C/S应用的例子。但如果提供者有新数据需要下载,而客户端和提供者的连接已中断或者客户端甚至都未运行时,怎么办?客户端怎么知道有它等待的数据?推送通知就是为了解决这一问题。推送通知是提供者向设备或PC操作系统发送的短消息;操作系统又通过显示消息等方式,去通知客户端用户,有新的数据需要下载。如果用户在iOS上打开了(APNs)这个特性,并且应用程序也正确地注册了,则通知能发送到操作系统以及应用程序。APNs是推送通知的核心技术。

对于桌面系统的后台应用而言,推送通知也有同样的作用,而且不牺牲任何性能上的开销。对于当前未出于运行状态的程序——对于iOS则是指当前未在前台运行的程序——通知的呈现需要多一些步骤。操作系统接收到推送通知,通知用户。当用户收到警示消息时,用户可以选择启动相应的程序以向提供者下载数据。如果程序已经运行了,当通知到达时,应用程序会直接处理推送通知。

iOS提示:从4.0版本开始,程序可以在后台运行,但只能在一个限定的时间内。同一时间内只能有一个程序在前台运行。

正如其名,APNs使用“推”模式发送通知。“推”与“拉”不同,“拉”是接受者实时接收信息——在“推”模式下,操作系统是被动地接收而不是主动获取数据。推模式适用于在大范围并且实时性的消息传播,比较拉模式,它的伸缩性更小。APNs使用固定ip实现推送通知。

大部分推送通知由载体(payload)构成:一个包含了APNs预定义属性的属性列表,它定义了通知用户的方式。由于性能上的原因,载体被定义得很小(256字节)。尽管在载体中可以使用自定义属性,当使用远程通知来传输数据是不恰当的,因为推送通知并不能保证总是发送成功。关于载体的讨论,请参考“The NotificationPayload.”。

APNs保留它从提供者收到的最后的通知;因此,如果设备或PC一旦上线并且未接收过该通知,APNs会推送所保留的通知给它。iOS设备可以通过WiFi网络或者蜂窝网络连接接收推送通知;Mac则通过WiFi或有线网络接收推送通知。

重要:对于iOS,只有设备未连接蜂窝数据网或者iPod touch设备才使用Wi-Fi接收推送通知。对于一些使用WiFi接收推送通知的设备,设备的屏幕必须是打开的(屏幕不能是休眠状态),要么设备处于联机状态。iPad在休眠时会保持WiFi连接,因此能接收推送通知。WiFi讯号会唤醒主处理器以处理接收到的信号。

要在你的应用程序中使用远程通知,你应当从iOS或MacOS开发者中心获得相关证书,并且分别针对提供者和客户端进行编程。

“Provisioning and Development”讨论了激活步骤, “Provider Communication with Apple Push Notification Service”和 “Scheduling, Registering, and Handling Notifications”描述了实现的细节。

APNs 不停地监控提供者的随机行为,搜索活动的瞬时高峰,短暂的连接-重连接循环,以及类似的行为。苹果查找通知提供者中的这些行为,如果类似行为继续,它可能会把提供者的证书放入撤销证书列表并从此拒绝连接。任何持续的非法或可疑的行为都可能导致提供者无法访问APNs。