vds_ios/VDS/Classes/ModelHandlerPublisher.swift
Matt Bruce 552e0416d3 refactored out ModelHandlerPublishable and moved into the handler
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2022-08-12 15:27:50 -05:00

67 lines
2.3 KiB
Swift

//
// ModelHanlderPublisher.swift
// VDS
//
// Created by Matt Bruce on 8/12/22.
//
import Foundation
import Combine
extension Publishers {
public struct ModelHandlerPublisher<ModelHandlerType: ModelHandlerable>: Publisher {
public typealias Output = ModelHandlerType.ModelType
public typealias Failure = Never
private let modelHandler: ModelHandlerType
public init(modelHandler: ModelHandlerType) { self.modelHandler = modelHandler }
public func receive<S>(subscriber: S) where S : Subscriber, Never == S.Failure, ModelHandlerType.ModelType == S.Input {
let subscription = ModelHandlerSubscription(subscriber: subscriber, modelHandler: modelHandler)
subscriber.receive(subscription: subscription)
}
}
public class ModelHandlerSubscription<S: Subscriber, ModelHandlerType: ModelHandlerable>: Subscription where S.Input == ModelHandlerType.ModelType, S.Failure == Never {
private var subscriber: S?
private var modelHandler: ModelHandlerType?
public var subscribers = Set<AnyCancellable>()
public init(subscriber: S, modelHandler: ModelHandlerType) {
self.subscriber = subscriber
self.modelHandler = modelHandler
subscribe()
}
public func request(_ demand: Subscribers.Demand) { }
public func cancel() {
subscriber = nil
modelHandler = nil
}
private func subscribe() {
guard let publisher = modelHandler?.modelPublisher else { return }
publisher.debounce(for: .seconds(Constants.ModelStateDebounce), scheduler: RunLoop.main).sink { [weak self] viewModel in
guard let self else { return }
_ = self.subscriber?.receive(viewModel)
}.store(in: &subscribers)
}
}
}
extension ModelHandlerable {
public var handlerPublisher: Publishers.ModelHandlerPublisher<Self> {
return Publishers.ModelHandlerPublisher(modelHandler: self)
}
public func createBinding(with subject: CurrentValueSubject<ModelType, Never>, storeIn subscriptions: inout Set<AnyCancellable>) {
handlerPublisher.sink { (value) in
subject.send(value)
}.store(in: &subscriptions)
}
}