Created
July 13, 2018 23:55
-
-
Save albertbori/0b196be861be609c1166dfe7a39f8a12 to your computer and use it in GitHub Desktop.
NotificationCenter alternative using enums and delegates (fully swift)
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
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