ios - 简化 swift 通知中心事件和观察者
问题描述
我最近开始了新的 swift 项目。我想简化通知和通知观察者的使用,所以为此编写了一些代码。所以我想分享这段代码并询问任何可能的问题?
事件,将事件发布到通知中心的类
import Foundation
enum EventName: String {
case ProfileUpdate
case ApplicationDidPreload
}
class Event {
static let shared: Event = Event()
/// Post event to notification center
/// - Parameter event: event name to post
/// - Parameter object: data you're going to pass
/// - Parameter userInfo: user info
func post(event: EventName, object: Any? = nil, userInfo: [AnyHashable : Any]? = nil) {
let notification: Notification = Notification(name: Notification.Name(rawValue: event.rawValue), object: object, userInfo: userInfo)
NotificationCenter.default.post(notification)
}
}
事件监听器类,有几个方法来观察通知。当数据传递给通知时,我想处理这两种情况。
import Foundation
class EventListener {
typealias callback = () -> ()
typealias callbackWithData = (_ data: Any) -> ()
static let shared: EventListener = EventListener()
private var callback: callback?
private var callbackWithData: callbackWithData?
/// Listen event which not return any data in callback closure
/// Parameter event: event name to listen
/// Parameter callback: callback closure
func listenEvent(event: EventName, callback: @escaping callback) {
self.callback = callback
self.addObserver(event: event)
}
/// Listen event which returns data in callback closure
/// Parameter event: event name to listen
/// Parameter callback: callback closure
func listenEvent(event: EventName, callbackWithData: @escaping callbackWithData) {
self.callbackWithData = callbackWithData
self.addObserver(event: event)
}
/// Add and setup observer to notification center
private func addObserver(event: EventName) {
NotificationCenter.default.addObserver(self,
selector: #selector(self.handler),
name: NSNotification.Name(rawValue: event.rawValue),
object: nil)
}
/// Handle notification observer
@objc private func handler(notification: Notification) {
guard let data = notification.object else {
self.callback?()
return
}
self.callbackWithData?(data)
}
}
使用示例
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
Event.shared.post(event: .ApplicationDidPreload)
Event.shared.post(event: .ProfileUpdate, object: 1)
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
EventListener.shared.listenEvent(event: .ApplicationDidPreload, callback: self.test1)
EventListener.shared.listenEvent(event: .ProfileUpdate, callbackWithData: self.test2)
}
private func test1() {
print("preloaded")
}
private func test2(data: Any) {
print("profile id")
let Id: Int? = data as? Int
print(Id)
}
}
解决方案
恕我直言,用于发布到通知中心的 Event 类不是必需的,最好扩展 Notification.Name 之类的
extension Notification.Name {
static let MyNotificationName = Notification.Name("MyNotificationName")
}
这使您可以仅用.MyNotificationName
作通知名称。
要在收听通知时使用块,您还可以使用现有的基于块的观察者版本:
func addObserver(forName name: NSNotification.Name?,
object obj: Any?,
queue: OperationQueue?,
using block: @escaping (Notification) -> Void) -> NSObjectProtocol
推荐阅读
- apache-spark - Spark:在本地使用原生 hadoop 库
- c# - 使用 IronPDF 生成 HTML 目录
- visual-studio - VS2019实现与SQL server的认证
- vue.js - 如何使用 webpack web 应用程序加速我的 .NET core + Vuejs?
- javascript - 将事件附加到元素并正确调度它
- node.js - 如何找出导致我的 nodejs 代码消耗大量内存的原因?
- typescript - 如何与 tsrynge 共享相同的依赖注入树?
- android - kotlin - 比将活动传递给非活动类更好的方法是什么
- powershell - Powershell的Get-ChildItem中“模式”列中的空值是什么意思?
- python - Flask:如果最后一个请求尚未完成,如何忽略新请求