Last active
July 1, 2024 09:32
-
-
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
public protocol CustomTypedNotification: TypedNotification {} | |
extension CustomTypedNotification { | |
public static var name: Notification.Name { | |
return .init(String(reflecting: self)) | |
} | |
public static func generate(from notification: Notification) -> Self { | |
let notificationKey = TypedUserInfo.notificationUserInfoKey | |
guard let result = notification.userInfo?[notificationKey] as? Self else { | |
preconditionFailure("\(Self.self) value not found in userInfo") | |
} | |
return result | |
} | |
} | |
extension TypedUserInfo { | |
fileprivate static let notificationUserInfoKey = "TypedNotificationUserInfoKey" | |
} | |
extension NotificationCenter { | |
public 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
public protocol TypedNotification { | |
static var name: Notification.Name { get } | |
static func generate(from notification: Notification) -> Self | |
} | |
public struct TypedUserInfo { | |
private let userInfo: [AnyHashable: Any] | |
public init(_ userInfo: [AnyHashable: Any]?) { | |
self.userInfo = userInfo ?? [:] | |
} | |
public subscript<Value>(key: AnyHashable) -> Value? { | |
return userInfo[key] as? Value | |
} | |
} | |
extension NotificationCenter { | |
public 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) { note in | |
let notification = T.generate(from: note) | |
block(notification) | |
} | |
} | |
public 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() | |
} | |
} |
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
public class BaseKeyboardNotification: TypedNotification, CustomDebugStringConvertible { | |
public class var name: Notification.Name { preconditionFailure("Must override") } | |
public let isLocal: Bool | |
public let frameBegin: CGRect | |
public let frameEnd: CGRect | |
public let animationDuration: TimeInterval | |
public let animationCurve: UIView.AnimationCurve | |
public 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 | |
let curveValue: Int = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] ?? 0 | |
self.animationCurve = UIView.AnimationCurve(rawValue: curveValue) ?? .easeInOut | |
} | |
public var debugDescription: String { | |
return """ | |
\(Self.name.rawValue) - frameBegin: \(frameBegin), frameEnd: \(frameEnd), \ | |
duration: \(animationDuration) | |
""" | |
} | |
} | |
public enum KeyboardNotification { | |
public class WillShow: BaseKeyboardNotification { | |
override public class var name: Notification.Name { | |
UIResponder.keyboardWillShowNotification | |
} | |
} | |
public class DidShow: BaseKeyboardNotification { | |
override public class var name: Notification.Name { | |
UIResponder.keyboardDidShowNotification | |
} | |
} | |
public class WillHide: BaseKeyboardNotification { | |
override public class var name: Notification.Name { | |
UIResponder.keyboardWillHideNotification | |
} | |
} | |
public class DidHide: BaseKeyboardNotification { | |
override public class var name: Notification.Name { | |
UIResponder.keyboardDidHideNotification | |
} | |
} | |
public class WillChangeFrame: BaseKeyboardNotification { | |
override public class var name: Notification.Name { | |
UIResponder.keyboardWillChangeFrameNotification | |
} | |
} | |
public class DidChangeFrame: BaseKeyboardNotification { | |
override public class var name: Notification.Name { | |
UIResponder.keyboardDidChangeFrameNotification | |
} | |
} | |
} | |
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