TypedNotification
TypedNotification is a Swift library that adds some type-safety to
Foundation’s NotificationCenter. The library is small and can be added to your
project either as a static framework or by directly including the single source
file.
Usage
Playground
This repository includes an annotated playground that demonstrates the features of TypedNotification. To use it:
- Clone the repository.
- Open
TypedNotification.xcworkspace - Build the TypedNotification (Playground) scheme.
- Open the Demo playground and run it.
Overview
For each notification in your application, create a new type that conforms to
the TypedNotification protocol:
struct DataStoreDidSaveNotification: TypedNotification {
/// The data store posting the notification.
let object: DataStore // <- This property is required by the protocol.
let insertedObjects: Set<Model>
}
When conforming, you must provide a type and the storage for an object attached
to the notification. Additional data that would normally be included in a
notification’s userInfo dictionary can be provided as properties on the
notification.
To post a notification, create an instance of the notification and call post(_:)
on a NotificationCenter:
NotificationCenter.default.post(DataStoreDidSaveNotification(object: dataStore, insertedObjects: insertedObjects))
To observe a notification use the addObserver(forType:object:queue:using)
method on NotificationCenter. This is similar to the Foundation method but
takes a type of notification to observe instead of the name and returns a
NotificationObservation to manage the observation:
let observation = NotificationCenter.default.addObserver(forType: DataStoreDidSaveNotification.self, object: nil, queue: nil) { note in
print(note.insertedObjects)
}
Note that the type of note passed to the callback block is a
DataStoreDidSaveNotification.
The returned NotificationObservation instance manages the lifetime of the
observation. When the instance is deallocated, the observation stops.
Notification Observation Bags
TypedNotification provides a convenient type for working with
NotificationObservations. A NotificationObservationBag stores multiple
observation instances and removes them all when deallocated. You can use this to
tie the lifetime of an observation to another object:
class ViewController: UIViewController {
let notificationBag = NotificationObservationBag()
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(forType: DataStoreDidSaveNotification.self, object: nil, queue: nil) { [unowned self] note in
self.doSomething(with: note.insertedObjects)
}
.stored(in: notificationBag)
}
}
Here, when a ViewController is deallocated, so to is its notification bag and
the observation set up in viewDidLoad() goes away.
This is really useful behaviour so TypedNotification includes a variant of
addObserver for normal Notifications that also returns a
NotificationObservation:
func setUpKeyboardObservation() {
NotificationCenter.default.addObserver(forNotificationNamed: UIWindow.keyboardWillShowNotification, object: nil, queue: nil) { note in
print(note.userInfo?[UIWindow.keyboardFrameEndUserInfoKey])
}
.stored(in: notificationBag)
}
Requirements & Installation
TypedNotification requires a version of Xcode that can compile Swift 5
code. Additionally it requires a deployment target targeting iOS 10+ or macOS
10.12+ because of a dependency on os.lock.
You’ve got four options for installation.
Manual Installation
Copy TypedNotification.swift from the Sources directory.
CocoaPods
Add the following to your Podfile:
pod 'AJJTypedNotification', '~> 2.0'
Note that the name of the module (i.e., what you import) is
TypedNotification but the pod is AJJTypedNotification.
Carthage
Add the following to your Cartfile:
github "alexjohnj/TypedNotification" ~> 2.0
TypedNotification builds as a static framework so you’ll find the output in
Build/$PLATFORM/Static. Remember not to embed the framework in your
application, just link against it.
Swift Package Manager
Add the following to your Package.swift file’s dependencies:
dependencies: [
.package(url: "https://github.com/alexjohnj/TypedNotification.git", .upToNextMinor(from: "2.0.0"))
]
License
MIT
View on GitHub
TypedNotification Reference