A Protocol-Oriented NotificationCenter which is type safe, thread safe and with memory safety.
-
Type Safe
No more
userInfodictionary and Downcasting, just deliver the concrete type value to the observer. -
Thread Safe
You can
register,notify,unregisterin any thread without crash and data corruption. -
Memory Safety
SwiftNotificationCenterstore the observer as a zeroing-weak reference. No crash and no need tounregistermanually.
It's simple, safe, lightweight and easy to use for one-to-many communication.
Define protocol and observer:
protocol Update {
func updateTitle(title: String)
}
extension ViewController: Update {
func updateTitle(title: String) {
self.titleLabel.text = title
}
}
let vc = ViewController()Register:
Broadcaster.register(Update.self, observer: vc)Broadcast:
Broadcaster.notify(Update.self) {
$0.updateTitle("new title")
}Unregister:
Broadcaster.unregister(Update.self, observer: self)Compare with NSNotificationCenter :
For example, handle UIKeyboardWillShowNotification
@objc func handleKeyboardNotification(notification: NSNotification) {
guard notification.name == NSNotification.Name.UIKeyboardWillShow
else { return }
guard let beginFrame = (notification
.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue
else { return }
guard let endFrame = (notification
.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
else { return }
// use beginFrame, endFrame
}SwiftNotificationCenter way:
/*
If you want to observe the system built in notifications like this.
You can declare a protocol and the relevant method, and use a singleton as a mediator to observe system's notification, then notify our observers.
Please check the refactor example in SwiftNotificationCenterExample Project.
*/
func UIKeyboardWillShow(beginFrame: CGRect, endFrame: CGRect) {
}Broadcaster.notify runs its callbacks synchronously on the calling thread or
queue, using a snapshot of the currently live observers. Registration and
removal are queued behind internal barriers; a subsequent notification observes
those earlier changes. Callbacks may register, unregister, or issue a nested
notification without changing the current notification's snapshot.
Use bounded concurrency when many callers notify at once. Submitting an unbounded number of blocking callers to a shared Dispatch worker pool can exhaust its workers while the internal barrier work is waiting to run. Thread safety does not imply a progress guarantee at arbitrary parallelism.
Add https://github.com/100mango/SwiftNotificationCenter.git as a package
dependency in Xcode, choose version 1.1.0 or later, and add the
SwiftNotificationCenter product to your target. Version 1.1.0 is the first
release with Swift Package Manager support; 1.0.5 and earlier do not include
Package.swift.
In another package's Package.swift, use:
dependencies: [
.package(
url: "https://github.com/100mango/SwiftNotificationCenter.git",
from: "1.1.0"
)
],
targets: [
.target(name: "YourTarget", dependencies: ["SwiftNotificationCenter"])
]Then import SwiftNotificationCenter in your Swift files. For local development,
add the checkout as a local package in Xcode or use
.package(path: "../SwiftNotificationCenter").
The manifest uses Swift tools 5.0 and Swift 5 language mode, and retains the library's declared iOS 8.0 and macOS 10.9 deployment targets. The installed Xcode/Swift toolchain may require a newer deployment target. CocoaPods and Carthage installation remain unchanged.
pod 'SwiftNotificationCenter'
github "100mango/SwiftNotificationCenter"
Just copy source files in the SwiftNotificationCenter folder into your project.
Run the package tests from the repository root with a current Swift toolchain:
swift build
swift test
swift test --configuration releaseThe package builds the library sources directly and reuses the Xcode test suite. It does not include the UIKit example application, umbrella header, or Xcode Info.plist files. The Foundation-only library can also be tested on Linux; Apple-platform builds still require an appropriate Xcode SDK.
SwiftNotificationCenter is under the MIT license.
