58 lines
1.8 KiB
Swift
58 lines
1.8 KiB
Swift
import CoreDomain
|
||
import CoreModel
|
||
import Observation
|
||
|
||
@MainActor
|
||
@Observable
|
||
public final class HomeViewModel {
|
||
public private(set) var uiState: HomeUiState = .loading
|
||
|
||
private let homeUseCase: HomeUseCase
|
||
private let sessionUseCase: SessionUseCase
|
||
private var loadTask: Task<Void, Never>?
|
||
private var dataTask: Task<Void, Never>?
|
||
|
||
public init(homeUseCase: HomeUseCase, sessionUseCase: SessionUseCase) {
|
||
self.homeUseCase = homeUseCase
|
||
self.sessionUseCase = sessionUseCase
|
||
}
|
||
|
||
public func load() {
|
||
// flatMapLatest 的等价:登录态变化时重新订阅对应数据源。
|
||
loadTask?.cancel()
|
||
loadTask = Task { [weak self] in
|
||
guard let self else { return }
|
||
do {
|
||
for try await isLoggedIn in self.sessionUseCase.observeIsLoggedIn() {
|
||
self.reload(isLoggedIn: isLoggedIn)
|
||
}
|
||
} catch is CancellationError {
|
||
} catch {
|
||
self.uiState = .error(error.localizedDescription)
|
||
}
|
||
}
|
||
}
|
||
|
||
private func reload(isLoggedIn: Bool) {
|
||
dataTask?.cancel()
|
||
uiState = .loading
|
||
dataTask = Task { [weak self] in
|
||
guard let self else { return }
|
||
do {
|
||
if isLoggedIn {
|
||
for try await data in self.homeUseCase.observeHome() {
|
||
self.uiState = .success(data, isGuest: false)
|
||
}
|
||
} else {
|
||
for try await data in self.homeUseCase.observeGuestHome() {
|
||
self.uiState = .success(data, isGuest: true)
|
||
}
|
||
}
|
||
} catch is CancellationError {
|
||
} catch {
|
||
self.uiState = .error(error.localizedDescription)
|
||
}
|
||
}
|
||
}
|
||
}
|