Created
September 9, 2022 15:10
-
-
Save devahmedshendy/3be8bc3e9ad3d96a3d8ac0922904a692 to your computer and use it in GitHub Desktop.
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
final class UnitsViewModel { | |
// MARK: - Public Members/Methods | |
let onLoadingMoreUnits = PassthroughSubject<Bool, Never>() | |
let onInitialResult = PassthroughSubject<[UnitDto], Never>() | |
let onError = PassthroughSubject<HighLevelError.Reason, Never>() | |
var moreUnitsToLoad: Bool { | |
unitsQueue.isNotEmpty | |
} | |
// MARK: - Properties | |
private var unitsQueue = [UnitDto]() | |
private let publicUnitsSubject = CurrentValueSubject<[UnitDto], Never>([]) | |
private var repository: Repository | |
private var subscription: AnyCancellable? | |
private var processUnitsSubscriptions: AnyCancellable? | |
private var unitsResultSubscription: AnyCancellable? | |
private var bindOnPrivateUnitsSubs: AnyCancellable? | |
// MARK: - init | |
init(repository: Repository) { | |
self.repository = repository | |
loadAllUnits() | |
} | |
// MARK: - Operations | |
private func loadAllUnits() { | |
unitsResultSubscription?.cancel() | |
unitsResultSubscription = nil | |
unitsResultSubscription = repository | |
.getUnits() | |
.sink( | |
receiveCompletion: (onCompletionHandler(_:)), | |
receiveValue: (onUnitsResultHandler(models:)) | |
) | |
} | |
private func onUnitsResultHandler(models: [UnitModel]) { | |
let units = models.map(UnitDto.init(from:)) | |
unitsQueue.append(contentsOf: units) | |
processUnits() | |
} | |
func processUnits() { | |
if !moreUnitsToLoad { return } | |
processUnitsSubscriptions?.cancel() | |
processUnitsSubscriptions = nil | |
onLoadingMoreUnits.send(true) | |
processUnitsSubscriptions = unitsQueue.enqueue(count: 3) | |
.publisherWithFailure | |
.flatMap(maxPublishers: .max(1), loadTotalUpdates(into:)) | |
.collect() | |
.sink( | |
receiveCompletion: (onCompletionHandler(_:)), | |
receiveValue: (onInitialResultHandler(_ :)) | |
) | |
} | |
private func onInitialResultHandler(_ units: [UnitDto]) { | |
onInitialResult.send(units) | |
onLoadingMoreUnits.send(false) | |
} | |
private func onCompletionHandler(_ completion: HighLevelCompletion) { | |
if case let .failure(error) = completion { | |
onError.send(error.reason) | |
print(error) | |
} | |
} | |
private func loadTotalUpdates(into unit: UnitDto) -> AnyPublisher<UnitDto, HighLevelError> { | |
return repository | |
.loadUpdates(for: UnitModel(from: unit)) | |
.map(unit.applyUpdates(_:)) | |
.eraseToAnyPublisher() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment