Type-Safe NotificationCenter
Type-safe wrapper around NotificationCenter with AsyncStream support.
struct TypedNotification<Payload> {
let name: Notification.Name
init(_ name: String) {
self.name = Notification.Name(name)
}
}
extension NotificationCenter {
func post<Payload>(_ notification: TypedNotification<Payload>, payload: Payload) {
post(name: notification.name, object: nil, userInfo: ["payload": payload])
}
func publisher<Payload>(for notification: TypedNotification<Payload>) -> AsyncStream<Payload> {
AsyncStream { continuation in
let observer = addObserver(
forName: notification.name,
object: nil,
queue: nil
) { notification in
if let payload = notification.userInfo?["payload"] as? Payload {
continuation.yield(payload)
}
}
continuation.onTermination = { @Sendable _ in
self.removeObserver(observer)
}
}
}
}
// Usage:
// enum Notifications {
// static let userLoggedIn = TypedNotification<User>("userLoggedIn")
// }
// NotificationCenter.default.post(.userLoggedIn, payload: user)
// for await user in NotificationCenter.default.publisher(for: .userLoggedIn) { }