Last active
June 15, 2023 03:08
-
-
Save nearfri/67c43f91230c42d550c5980cd02a5607 to your computer and use it in GitHub Desktop.
Typed Notification
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
protocol TypedNotification { | |
static var name: Notification.Name { get } | |
static func generate(from notification: Notification) -> Self | |
} | |
protocol CustomTypedNotification: TypedNotification {} | |
extension CustomTypedNotification { | |
static var name: Notification.Name { | |
return .init(String(reflecting: self)) | |
} | |
static func generate(from notification: Notification) -> Self { | |
let notificatonKey = TypedUserInfo.notificationUserInfoKey | |
guard let result = notification.userInfo?[notificatonKey] as? Self else { | |
preconditionFailure("\(Self.self) value not found in userInfo") | |
} | |
return result | |
} | |
} | |
struct TypedUserInfo { | |
fileprivate static let notificationUserInfoKey = "TypedNotificationUserInfoKey" | |
private let userInfo: [AnyHashable: Any] | |
init(_ userInfo: [AnyHashable: Any]?) { | |
self.userInfo = userInfo ?? [:] | |
} | |
subscript<Value>(key: AnyHashable) -> Value? { | |
return userInfo[key] as? Value | |
} | |
} | |
extension NotificationCenter { | |
func addObserver<T: TypedNotification>( | |
for notification: T.Type, | |
object: Any? = nil, | |
queue: OperationQueue? = nil, | |
using block: @escaping (T) -> Void | |
) -> NSObjectProtocol { | |
return addObserver(forName: T.name, object: object, queue: queue) { noti in | |
let notification = T.generate(from: noti) | |
block(notification) | |
} | |
} | |
func publisher<T: TypedNotification>( | |
for notification: T.Type, | |
object: AnyObject? = nil | |
) -> AnyPublisher<T, Never> { | |
return publisher(for: T.name, object: object) | |
.map(T.generate(from:)) | |
.eraseToAnyPublisher() | |
} | |
func post<T: CustomTypedNotification>(_ notification: T, object: AnyObject? = nil) { | |
let userInfo: [AnyHashable: Any] = [TypedUserInfo.notificationUserInfoKey: notification] | |
post(name: T.name, object: object, userInfo: userInfo) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class BaseKeyboardNotification: TypedNotification { | |
class var name: Notification.Name { preconditionFailure("Must override") } | |
var isLocal: Bool | |
var frameBegin: CGRect | |
var frameEnd: CGRect | |
var animationDuration: TimeInterval | |
static func generate(from notification: Notification) -> Self { | |
return Self.init(notification) | |
} | |
required init(_ notification: Notification) { | |
let userInfo = TypedUserInfo(notification.userInfo) | |
self.isLocal = userInfo[UIResponder.keyboardIsLocalUserInfoKey] ?? false | |
self.frameBegin = userInfo[UIResponder.keyboardFrameBeginUserInfoKey] ?? .null | |
self.frameEnd = userInfo[UIResponder.keyboardFrameEndUserInfoKey] ?? .null | |
self.animationDuration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] ?? 0 | |
} | |
} | |
class KeyboardWillShowNotification: BaseKeyboardNotification { | |
override class var name: Notification.Name { UIResponder.keyboardWillShowNotification } | |
} | |
class KeyboardWillHideNotification: BaseKeyboardNotification { | |
override class var name: Notification.Name { UIResponder.keyboardWillHideNotification } | |
} | |
token = nc.addObserver(for: KeyboardWillShowNotification.self) { note in | |
print(note.animationDuration) | |
} | |
nc.publisher(for: KeyboardWillShowNotification.self).sink { note in | |
print(note.animationDuration) | |
} | |
.store(in: &subscriptions) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct LocalMessageNotification: CustomTypedNotification { | |
let id: String | |
var message: String | |
} | |
NotificationCenter.default.publisher(for: LocalMessageNotification.self).sink { note in | |
print("id: \(note.id)") | |
print("message: \(note.message)") | |
} | |
.store(in: &subscriptions) | |
NotificationCenter.default.post(LocalMessageNotification(id: "1", message: "hello")) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment