Skip to content

Instantly share code, notes, and snippets.

@albertbori
Created July 13, 2018 23:55
Show Gist options
  • Save albertbori/0b196be861be609c1166dfe7a39f8a12 to your computer and use it in GitHub Desktop.
Save albertbori/0b196be861be609c1166dfe7a39f8a12 to your computer and use it in GitHub Desktop.
NotificationCenter alternative using enums and delegates (fully swift)
import Foundation
import PlaygroundSupport
//class that allows fully-swift weak reference storage for arrays/dictionaries
class Weak<T> {
private weak var _object: AnyObject?
var object: T? { return _object as? T }
init(object: T) {
_object = object as AnyObject
}
}
enum LocalNotificationType {
case replyCreated
}
enum LocalNotificationData {
case replyCreated(reply: String)
var type: LocalNotificationType {
switch self {
case .replyCreated: return .replyCreated
}
}
}
protocol LocalNotificationDelegate: class {
func handleNotification(data: LocalNotificationData)
}
//static class for convenience
class LocalNotifications {
fileprivate static var notificationDelegates: [LocalNotificationType: [Weak<LocalNotificationDelegate>]] = [:]
private static var _serialQueue = DispatchQueue(label: "LocalNotifications", qos: .background)
static func listen(for type: LocalNotificationType, on delegate: LocalNotificationDelegate) {
_serialQueue.async {
var delegates = self.notificationDelegates[type] ?? []
delegates.append(Weak(object: delegate))
notificationDelegates[type] = delegates
}
cleanDelegates(type: type)
}
static func send(notification data: LocalNotificationData) {
_serialQueue.async {
guard let delegates = notificationDelegates[data.type]?.filter({ $0.object != nil }).map({ $0.object! }) else { return }
for delegate in delegates {
DispatchQueue.main.async {
delegate.handleNotification(data: data)
}
}
}
cleanDelegates(type: data.type)
}
private static func cleanDelegates(type: LocalNotificationType) {
_serialQueue.async {
notificationDelegates[type] = notificationDelegates[type]?.filter({ $0.object != nil }) ?? []
}
}
}
//usage
class Test: LocalNotificationDelegate {
init() {
LocalNotifications.listen(for: .replyCreated, on: self)
}
func handleNotification(data: LocalNotificationData) {
switch data {
case .replyCreated(reply: let reply):
print("handled new reply: \"\(reply)\"")
}
}
}
print("Testing...")
var test: Test? = Test()
LocalNotifications.send(notification: .replyCreated(reply: "Hi!"))
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(250)) { //delay for deallocation
test = nil
}
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) { //delay for deallocation
LocalNotifications.send(notification: .replyCreated(reply: "Bye!"))
}
PlaygroundPage.current.needsIndefiniteExecution = true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment