Last active
September 3, 2020 15:57
-
-
Save SergLam/3bc0671c3455be24caf3233cddbba513 to your computer and use it in GitHub Desktop.
Singleton - notify many subscribers via weak objects set - inspired by article - https://nshipster.com/nshashtable-and-nsmaptable/
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
extension SocketClient { | |
enum Event: String, CaseIterable { | |
// Chat: | |
case sendMessage = "speak" | |
case typing = "typing" | |
case lastSeen = "last_seen" | |
case unreadConversations = "unread_conversations" | |
} | |
} |
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 SwiftyJSON | |
protocol SocketActionObserver: class { | |
func socketDidReceiveState(_ state: SocketClient.ChannelState, for channel: SocketClient.GChannel) | |
func socketDidReceiveResponse(for event: SocketClient.Event, data: JSON) | |
} | |
extension SocketActionObserver { | |
func observeSocket(for events: SocketClient.Event...) { | |
observeSocket(for: events) | |
} | |
func observeSocket(for events: [SocketClient.Event]) { | |
for event in events { | |
let observers = SocketClient.eventsObservers[event] ?? .init() | |
observers.insert(self) | |
SocketClient.eventsObservers[event] = observers | |
} | |
} | |
func stopObservingSocket(for events: SocketClient.Event...) { | |
for event in events { | |
guard let observers = SocketClient.eventsObservers[event] else { continue } | |
observers.remove(self) | |
SocketClient.eventsObservers[event] = observers | |
} | |
} | |
func stopObservingAllSocketEvents() { | |
for event in SocketClient.Event.allCases { | |
guard let observers = SocketClient.eventsObservers[event] else { continue } | |
observers.remove(self) | |
SocketClient.eventsObservers[event] = observers | |
} | |
} | |
} | |
// | |
extension SocketClient { | |
/// Socket event observers. | |
fileprivate static var eventsObservers: [SocketClient.Event: WeakSet<SocketActionObserver>] = [:] | |
/// Will go through all observers object for given socket event | |
/// and will call method related to this action. | |
/// | |
/// - Parameter event: Event about which observers will be notified. | |
/// - Parameter data: JSON data that came along with the event. | |
/// - Parameter queue: Operation queue, where the notification will happen. | |
func notifyObservers(about event: Event, with data: JSON, queue: OperationQueue = .main) { | |
guard let observers = SocketClient.eventsObservers[event]?.allObjects else { return } | |
queue.addOperation { observers.forEach { $0.socketDidReceiveResponse(for: event, data: data) } } | |
} | |
func notifyObservers(about state: SocketClient.ChannelState, queue: OperationQueue = .main) { | |
} | |
} |
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
// Usage: | |
import Foundation | |
import SwiftyJSON | |
class SocketClient { | |
// MARK: - Singleton | |
static let shared = SocketClient() | |
enum State: Int, Comparable { | |
case unknown = 0 // initial state | |
case disconnected // connection is not established | |
case rejected // connection is rejected | |
case connecting // connecting was started, but not yet finished | |
case connected // connection is established, but authentication is not confirmed | |
case authenticating // authentication was started, but not yet finished | |
case authenticated // connection is established AND authentication is confirmed | |
public static func < (left: State, right: State) -> Bool { left.rawValue < right.rawValue } | |
public static func <= (left: State, right: State) -> Bool { left.rawValue <= right.rawValue } | |
public static func > (left: State, right: State) -> Bool { left.rawValue > right.rawValue } | |
public static func >= (left: State, right: State) -> Bool { left.rawValue >= right.rawValue } | |
} | |
func receiveNewData(_ data: [String: Any]) { | |
SocketClient.shared.notifyObservers(about: .sendMessage, with: JSON(data)) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment