Skip to content

Instantly share code, notes, and snippets.

@SandeepAggarwal
Created July 18, 2021 12:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SandeepAggarwal/96800aad62fd225ebd7dd24fc9d6866f to your computer and use it in GitHub Desktop.
Save SandeepAggarwal/96800aad62fd225ebd7dd24fc9d6866f to your computer and use it in GitHub Desktop.
Demonstrates how Apple's NotificationCenter works
import Foundation
protocol MyNotificationCenterInterface {
func addObserver(_ observer: Any, selector: Selector, name: NSNotification.Name?, object: Any?)
func post(_ notification: Notification)
}
struct NotificationObserverData {
let observer: Any,
selector: Selector,
object: Any?
}
class MyNotificationCenter: MyNotificationCenterInterface {
private var map: [NSNotification.Name: [NotificationObserverData]] = [:]
static let shared = MyNotificationCenter()
func addObserver(_ observer: Any, selector: Selector, name: NSNotification.Name?, object: Any?) {
guard let name = name else { return }
let data = NotificationObserverData(observer: observer, selector: selector, object: object)
if var values = map[name] {
values.append(data)
map[name] = values
} else {
map[name] = [data]
}
}
func post(_ notification: Notification) {
guard let dataItems = map[notification.name] else { return }
for item in dataItems {
guard equals(item.object, notification.object) else {
print("Unauthorised object sending the notification. Blocked!")
return
}
if let objectObserver = item.observer as? NSObject {
objectObserver.performSelector(onMainThread: item.selector, with: item.object, waitUntilDone: true)
} else {
//Note: This gets executed a bit late than performSelector
DispatchQueue.main.async {
Thread.detachNewThreadSelector(item.selector, toTarget: item.observer, with: item.object)
}
}
}
}
}
let notifName = NSNotification.Name.init("hello")
class A: NSObject {
let b = B()
override init() {
super.init()
let selector = #selector(b.tellMe(sender:))
MyNotificationCenter.shared.addObserver(b, selector: selector, name: notifName, object: self)
}
func notifyB() {
MyNotificationCenter.shared.post(Notification(name: notifName, object: self))
}
}
class B {
@objc func tellMe(sender: Any) {
print("Notification received! with sender: \(sender)")
}
}
let a = A()
a.notifyB()
//This equals method credits to: https://stackoverflow.com/a/61050386/3632958
func equals(_ x : Any?, _ y : Any?) -> Bool {
guard x is AnyHashable else { return false }
guard y is AnyHashable else { return false }
return (x as! AnyHashable) == (y as! AnyHashable)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment