背景
當(dāng)使用NotificationCenter
發(fā)通知傳遞數(shù)據(jù)時巨朦,通常需要繁復(fù)的解包,麻煩還容易出錯关拒,所以針對該問題對NotificationCenter
進(jìn)行了傳遞數(shù)據(jù)模型的封裝思灌。
依賴
由于RxSwift
封裝的NotificationCenter
對生命周期控制的很好,所以我們基于它開發(fā)发魄。
兼容
考慮到只是對NotificationCenter
的封裝,所以我們需要很好的支持NotificationCenter
原生功能俩垃。所以開發(fā)都是基于NotificationCenter
的擴(kuò)展励幼。
使用
- 配置通知
extension NotificationCenter.BaseName {
/// 通知別名
typealias Name = NotificationCenter.Name
/// 名稱改變了
static let nameChanged = Name<String>(name: "nameChanged")
}
- 發(fā)送與監(jiān)聽
/// 發(fā)送
NotificationCenter.post(.nameChanged , data: "新名稱")
/// 監(jiān)聽
NotificationCenter.notification(.nameChanged).subscribe(onNext: { [weak self] result in
guard let self = self else { return }
if let name = result.data {
// ...
}
}).disposed(by: rx.disposeBag)
設(shè)計實現(xiàn)
- 首先是對數(shù)據(jù)模型的封裝, 數(shù)據(jù)模型使用泛型支持?jǐn)?shù)據(jù)類型
public extension NotificationCenter {
/// 通知配置
final class Name<T>: BaseName { }
/// 通知配置
class BaseName {
/// 通知名稱
public let name: String
/// 自定義dataKey
public let dataKey: String
/// 初始化
/// - Parameters:
/// - name: 通知名
/// - dataKey: 自定義dataKey,默認(rèn)為空吆寨,默認(rèn)為name
public init(name: String, dataKey: String? = nil) {
self.name = name
self.dataKey = dataKey ?? name
}
/// 初始化
/// - Parameters:
/// - name: 通知名
/// - dataKey: 自定義dataKey赏淌,默認(rèn)為空踩寇,默認(rèn)為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)
}
}
/// 通知結(jié)果
class NotificationResult<T> {
/// 泛型數(shù)據(jù)
let data: T?
/// 通知全部數(shù)據(jù)
let notification: Notification
/// 通知來源
var object: Any? {
return notification.object
}
/// 通知信息
var userInfo: [AnyHashable : Any]? {
return notification.userInfo
}
/// 初始化
/// - Parameters:
/// - data: 泛型數(shù)據(jù)
/// - notification: 通知數(shù)據(jù)
init(data: T?, notification: Notification) {
self.data = data
self.notification = notification
}
}
}
- 發(fā)送通知和接收通知
public extension NotificationCenter {
/// 發(fā)送通知
/// - Parameters:
/// - name: 項目名稱配置
/// - data: 數(shù)據(jù)
/// - object: 發(fā)送源
static func post<T>(_ name: Name<T>, 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)
}
/// 監(jiān)聽通知
/// - Parameter name: 項目名稱配置
/// - Returns: 可見聽數(shù)據(jù)
static func notification<T>(_ name: Name<T>) -> Observable<NotificationResult<T>> {
NotificationCenter.default.rx.notification(name.notificationName).map { notify -> NotificationResult<T> in
let userInfo = notify.userInfo
let data = userInfo?[name.dataKey] as? T
let result = NotificationResult.init(data: data, notification: notify)
return result
}
}
/// 發(fā)送通知(對象方法)
/// - Parameters:
/// - name: 項目名稱配置
/// - data: 數(shù)據(jù)
/// - object: 發(fā)送源
func post<T>(_ name: Name<T>, data: T? = nil, object: Any? = nil) {
NotificationCenter.post(name, data: data, object: object)
}
/// 監(jiān)聽通知(對象方法)
/// - Parameter name: 項目名稱配置
/// - Returns: 可見聽數(shù)據(jù)
func notification<T>(_ name: Name<T>) -> Observable<NotificationResult<T>> {
return NotificationCenter.notification(name)
}
}