pls*_*pls 8 uitableview swift rx-swift moya
我目前正在使用Moya来发出我的网络请求.我已经从其中一个示例项目实现了以下内容@ https://github.com/DroidsOnRoids/RxSwiftExamples#tutorials
下面我设置了restaurantSearch,这样当有人输入文本时,它会发出新的请求.
var restaurantSearch: Observable<(String)> {
return searchBar
.rx_text
.throttle(0.5, scheduler: MainScheduler.instance)
.distinctUntilChanged()
}
Run Code Online (Sandbox Code Playgroud)
我有一个方法返回类型[餐厅]的观察
func restaurants() -> Observable<[Restaurant]> {
return restaurantSearch
.observeOn(MainScheduler.instance)
.flatMapLatest { postcode -> Observable<[Restaurant]?> in
return self.getRestaurants(postcode, cuisine: "", restaurantName: "")
}.replaceNilWith([])
}
internal func getRestaurants(postcode: String, cuisine: String, restaurantName: String) -> Observable<[Restaurant]?> {
return self.justEatProvider
.request(.Restaurant(postcode, cuisine, restaurantName))
.debug()
.mapArrayOptional(Restaurant.self, keyPath: "Restaurants")
}
Run Code Online (Sandbox Code Playgroud)
我正在调用此方法并将其绑定到tableView,如下所示:
func setupRx() {
api = JustEatApi(provider: provider, restaurantSearch: restaurantSearch)
api
.restaurants()
.bindTo(tableView.rx_itemsWithCellIdentifier("RestaurantTableViewCell", cellType: RestaurantTableViewCell.self)) { (row, element, cell) in
cell.restaurant = element
}
.addDisposableTo(disposeBag)
}
Run Code Online (Sandbox Code Playgroud)
这工作正常.如果我输入一个邮政编码,它会进行搜索并填充tableView.
如果我关闭互联网并尝试更改邮政编码,则tableView保持原样.但是当我滚动它时,我的应用程序崩溃了以下内容:
@noreturn func rxFatalError(lastMessage: String) {
// The temptation to comment this line is great, but please don't, it's for your own good. The choice is yours.
fatalError(lastMessage)
}
Run Code Online (Sandbox Code Playgroud)
此外,如果我不滚动,而只是转回互联网并更改邮政编码没有任何反应.似乎它失去了它的约束力.
首先,我尝试在bindTo方法调用之前添加catchOnError,但我在评论中读到它不应该作为UIBinding的一部分来处理:http://blog.scottlogic.com/2014/05/11/reactivecocoa-tableview-binding.html
我猜我应该在方法中处理它:
func restaurants() -> Observable<[Restaurant]> {
return restaurantSearch
.observeOn(MainScheduler.instance)
.flatMapLatest { postcode -> Observable<[Restaurant]?> in
return self.getRestaurants(postcode, cuisine: "", restaurantName: "")
}.replaceNilWith([])
}
Run Code Online (Sandbox Code Playgroud)
所以我有两个问题:
1)我应该在何处以及如何处理网络错误?
2)为什么在我重新上网后tableView没有更新?
任何帮助非常感谢.
muv*_*aaa 10
我亲自处理制作/解析网络请求的服务中的网络错误.这样做的好方法是将你的网络结果包装成某种枚举(类似于可选,但如果为n则有错误).所以你会有类似的东西:
enum APIResult<T> {
case Success(T)
case Error(ErrorType)
}
Run Code Online (Sandbox Code Playgroud)
然后你的服务将返回这样的东西
Observable<APIResult<[Restaurant]>>
Run Code Online (Sandbox Code Playgroud)
如果使用MVVM体系结构,则只能在视图模型中过滤成功结果,并将该数据提供给视图控制器.
你还应该看一下Driver unit.它是专门为UI绑定制作的单元,因此它只在主线程上订阅,从不订阅错误并共享最后结果.
要将Observable转换为Driver,请使用以下三种方法之一:
func asDriver(onErrorJustReturn onErrorJustReturn: Self.E) -> RxCocoa.Driver<Self.E>
func asDriver(onErrorDriveWith onErrorDriveWith: RxCocoa.Driver<Self.E>) -> RxCocoa.Driver<Self.E>
func asDriver(onErrorRecover onErrorRecover: (error: ErrorType) -> RxCocoa.Driver<Self.E>) -> RxCocoa.Driver<Self.E>
Run Code Online (Sandbox Code Playgroud)
这种方法会自动处理你的第二个问题,因为当Observable发出错误时,所有订阅者都会取消订阅,即.它终止了流.尝试将.debug()放在你的api.restaurants()调用后面,然后自己看看它是否取消订阅.
您可以在此处阅读有关Driver和其他单元的更多信息
| 归档时间: |
|
| 查看次数: |
4362 次 |
| 最近记录: |