Skip to content

Instantly share code, notes, and snippets.

@mrfarukturgut
Created December 6, 2020 00:24
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 mrfarukturgut/e4f738e1f6462a3b5b47ae81d4575b29 to your computer and use it in GitHub Desktop.
Save mrfarukturgut/e4f738e1f6462a3b5b47ae81d4575b29 to your computer and use it in GitHub Desktop.
Publisher-Listener
import UIKit
import Foundation
enum Endpoint {
case profile
}
protocol Fetchable {
static var endpoint: Endpoint { get }
}
struct UserDTO: Codable {
var firstName: String
var lastName: String
var experiences: [Experience]
var resumes: [Resume]
}
extension UserDTO: Fetchable {
static var endpoint: Endpoint {
return .profile
}
}
struct Experience: Codable, Publishable {
var id: Int
var name: String
}
struct Resume: Codable, Publishable {
var id: Int
var name: String
}
protocol Fetcher {
associatedtype FetchableType: Fetchable
var data: FetchableType? { get set }
func fetch()
}
protocol Publishable {}
protocol Listener {
associatedtype ListeningType: Publishable
func received(_ data: ListeningType)
}
struct AnyListener<Type: Publishable>: Listener {
private let _received: (Type)->Void
init<P: Listener>(_ listener: P) where P.ListeningType == Type {
_received = listener.received
}
func received(_ data: Type) {
_received(data)
}
}
struct Publisher<Type: Publishable> {
// make this weak array
var listeners: [AnyListener<Type>] = []
func publish(_ data: Type) {
listeners.forEach({ $0.received(data) })
}
mutating func add<P: Listener>(_ listener: P) where P.ListeningType == Type {
self.listeners.append(AnyListener(listener))
}
}
class UserFetcher: Fetcher {
var data: UserDTO? {
didSet {
self.expPublisher.publish(data?.experiences ?? [])
}
}
let expPublisher: Publisher<[Experience]> = .init()
func fetch() {
print("Fetching from \(FetchableType.endpoint)")
self.data = UserDTO(firstName: "John", lastName: "Appleseed", experiences: [Experience(id: 1, name: "Developer")], resumes: [Resume(id: 1, name: "CV")])
}
}
extension Array: Publishable where Element: Publishable {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment