Created
December 6, 2020 00:24
-
-
Save mrfarukturgut/e4f738e1f6462a3b5b47ae81d4575b29 to your computer and use it in GitHub Desktop.
Publisher-Listener
This file contains hidden or 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 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