背景
当使用NotificationCenter
发通知传递数据时,通常需要繁复的解包,麻烦还容易出错,所以针对该问题对NotificationCenter
进行了传递数据模型的封装。
依赖
由于RxSwift
封装的NotificationCenter
对生命周期控制的很好,所以我们基于它开发。
兼容
考虑到只是对NotificationCenter
的封装,所以我们需要很好的支持NotificationCenter
原生功能。所以开发都是基于NotificationCenter
的扩展。
使用
- 配置通知
extension NotificationCenter.BaseName {
/// 通知别名
typealias Name = NotificationCenter.Name
/// 名称改变了
static let nameChanged = Name(name: "nameChanged")
}
- 发送与监听
/// 发送
NotificationCenter.post(.nameChanged , data: "新名称")
/// 监听
NotificationCenter.notification(.nameChanged).subscribe(onNext: { [weak self] result in
guard let self = self else { return }
if let name = result.data {
// ...
}
}).disposed(by: rx.disposeBag)
设计实现
- 首先是对数据模型的封装, 数据模型使用泛型支持数据类型
public extension NotificationCenter {
/// 通知配置
final class Name: BaseName { }
/// 通知配置
class BaseName {
/// 通知名称
public let name: String
/// 自定义dataKey
public let dataKey: String
/// 初始化
/// - Parameters:
/// - name: 通知名
/// - dataKey: 自定义dataKey,默认为空,默认为name
public init(name: String, dataKey: String? = nil) {
self.name = name
self.dataKey = dataKey ?? name
}
/// 初始化
/// - Parameters:
/// - name: 通知名
/// - dataKey: 自定义dataKey,默认为空,默认为name
public init(name: NSNotification.Name, dataKey: String? = nil) {
self.name = name.rawValue
self.dataKey = dataKey ?? name.rawValue
}
/// 通知名
var notificationName: NSNotification.Name {
return NSNotification.Name(rawValue: name)
}
}
/// 通知结果
class NotificationResult {
/// 泛型数据
let data: T?
/// 通知全部数据
let notification: Notification
/// 通知来源
var object: Any? {
return notification.object
}
/// 通知信息
var userInfo: [AnyHashable : Any]? {
return notification.userInfo
}
/// 初始化
/// - Parameters:
/// - data: 泛型数据
/// - notification: 通知数据
init(data: T?, notification: Notification) {
self.data = data
self.notification = notification
}
}
}
- 发送通知和接收通知
public extension NotificationCenter {
/// 发送通知
/// - Parameters:
/// - name: 项目名称配置
/// - data: 数据
/// - object: 发送源
static func post(_ name: Name, data: T? = nil, object: Any? = nil) {
var userInfo: [String: Any] = [:]
if let data = data {
userInfo[name.dataKey] = data
}
NotificationCenter.default.post(name: name.notificationName, object: object, userInfo: userInfo)
}
/// 监听通知
/// - Parameter name: 项目名称配置
/// - Returns: 可见听数据
static func notification(_ name: Name) -> Observable> {
NotificationCenter.default.rx.notification(name.notificationName).map { notify -> NotificationResult in
let userInfo = notify.userInfo
let data = userInfo?[name.dataKey] as? T
let result = NotificationResult.init(data: data, notification: notify)
return result
}
}
/// 发送通知(对象方法)
/// - Parameters:
/// - name: 项目名称配置
/// - data: 数据
/// - object: 发送源
func post(_ name: Name, data: T? = nil, object: Any? = nil) {
NotificationCenter.post(name, data: data, object: object)
}
/// 监听通知(对象方法)
/// - Parameter name: 项目名称配置
/// - Returns: 可见听数据
func notification(_ name: Name) -> Observable> {
return NotificationCenter.notification(name)
}
}