所有的终端产品都应该打造好自己的通知系统。
横幅通知,是终端应用实现消息传递的一种有效方式——它套用了「中断」这种经典的消息处理模式,可以穿透不同的上下文来投递消息。苹果是十分重视用户消息通知的。从一开始打造了APNs,到后来多次重构iOS系统的用户通知框架,足见其用心。
但对于App内的消息通知而言,iOS系统本地通知是比较鸡肋的——无法定制横幅的样式。现在要探讨的是,如何写一个自定义通知横幅的组件。
1 | 注:自定义通知横幅是17年的代码,整理为独立组件。 |
需求分析
App内的自定义通知横幅跟App外的系统通知横幅,功能特性是基本一致的:
- 通知消息接收、UI展示事件回调
- 用户交互事件回调
- 消息展示的UI定制
- 消息展示队列实现
整体可以参考UserNotification
框架:我们认为原始消息的有效载荷是核心,消息的展示过程是一个服务的过程。将消息加入队列,是发起申请服务的请求;展示给用户的是任务的描述(通知);用户对消息的处置是服务对请求任务的响应。
有几个技术细节需要考虑:
- 数据的交付。从接收到消息,到UI展示,最后到交互事件回调,这里有明确的数据流动。通知组件,怎么建立模型,怎么将数据打包并交付到业务层?
- 界面的定制。通知组件,如何支持业务层定制UI或交互特性?苹果是通过插件支持限制范围内的部分UI定制。交还多少控制权更合适?
- 服务请求队列。FIFO、优先级、可取消等特性的实现。
数据的交付。假设我们从业务端拿到的是JSON数据,是否需要将JSON转为模型实体数据(约束为特定的字段)?如果UI是支持自由定制的,考虑拓展性,那么是不能将载荷数据转为实体模型的。我们最终也是选择始终提供原始载荷数据(Payload),也就是,在UI定制阶段或者用户交互阶段,业务层是可以直接拿到原始载荷数据的。
界面的定制。因为界面除了UI的展示,还直接有用户的交互事件,交互事件是直接影响消息的流转流程的——手动关闭或者查看消息后,消息的展示队列会流转到下一条消息来展示。事件处理,需要中转,在组件内部完成流转,以及对业务层做事件分发。这部分需要将依赖注入到UI控件内。UI的定制一般通过接口实现或类继承来实现,交互逻辑是完全定制的。
队列,其实可以分为消息队列与展示队列。消息队列接收业务层推入的消息载荷,优先级+FIFO;展示队列则只是FIFO,通常情况下,展示队列还是个串行的队列——同一时间只能展示一个。消息队列与展示队列其实是一个生产消费的问题。
设计方案
Payload
数据载荷,这是流程的起点;HLTNotificationRequest
->Payload
,Request
是申请服务的请求,持有Payload
;HLTNotification
->HLTNotificationRequest
,Notification
是任务的描述,当任务进入展示队列后,Request
转化为Notification
;HLTNotificationView
->HLTNotification
,NotificationView
是通知界面,这里实现为通过类继承来实现UI定制;HLTNotificationResponse
->HLTNotification
,服务的响应,从NotifiationView
拿到的数据;HLTNotificationManager
,流程流转的管理。
实际实现上可能有些出入,队列实现的比较简单,需要后续优化一下。
其他
终端应用是直接面向用户的,用户体验为王。
Author: Jason
Permalink: http://blog.knpc21.com/ios/ios-lib-notification/
文章默认使用 CC BY-NC-SA 4.0 协议进行许可,使用时请注意遵守协议。
Comments