【发布时间】:2018-08-24 06:31:36
【问题描述】:
我的视图模型存在根本缺陷,因为使用驱动程序的视图模型将在返回错误时完成,并且无法自动重新订阅。
一个例子是我的PickerViewModel,它的界面是:
// MARK: Picker View Modelling
/**
Configures a picker view.
*/
public protocol PickerViewModelling {
/// The titles of the items to be displayed in the picker view.
var titles: Driver<[String]> { get }
/// The currently selected item.
var selectedItem: Driver<String?> { get }
/**
Allows for the fetching of the specific item at the given index.
- Parameter index: The index at which the desired item can be found.
- Returns: The item at the given index. `nil` if the index is invalid.
*/
func item(atIndex index: Int) -> String?
/**
To be called when the user selects an item.
- Parameter index: The index of the selected item.
*/
func selectItem(at index: Int)
}
Driver 问题的示例可以在我的CountryPickerViewModel 中找到:
init(client: APIClient, location: LocationService) {
selectedItem = selectedItemVariable.asDriver().map { $0?.name }
let isLoadingVariable = Variable(false)
let countryFetch = location.user
.startWith(nil)
.do(onNext: { _ in isLoadingVariable.value = true })
.flatMap { coordinate -> Observable<ItemsResponse<Country>> in
let url = try client.url(for: RootFetchEndpoint.countries(coordinate))
return Country.fetch(with: url, apiClient: client)
}
.do(onNext: { _ in isLoadingVariable.value = false },
onError: { _ in isLoadingVariable.value = false })
isEmpty = countryFetch.catchError { _ in countryFetch }.map { $0.items.count == 0 }.asDriver(onErrorJustReturn: true)
isLoading = isLoadingVariable.asDriver()
titles = countryFetch
.map { [weak self] response -> [String] in
guard let `self` = self else { return [] }
self.countries = response.items
return response.items.map { $0.name }
}
.asDriver(onErrorJustReturn: [])
}
}
titles 驱动UIPickerView,但当countryFetch 因错误而失败时,订阅完成且无法手动重试获取。
如果我尝试catchError,则不清楚我可以返回什么 observable,这些 observable 可以在用户恢复其互联网连接后重试。
任何justReturn 错误处理(asDriver(onErrorJustReturn:)、catchError(justReturn:))显然都会在返回值后立即完成,并且对于这个问题毫无用处。
我需要能够尝试获取,失败,然后显示一个 重试 按钮,该按钮将在视图模型上调用 refresh() 并重试。如何保持订阅开放?
如果答案需要重组我的视图模型,因为我正在尝试做的事情是不可能的或干净的,我愿意听到更好的解决方案。
【问题讨论】:
标签: swift mvvm viewmodel rx-swift