Tableview 未收到来自驱动程序的信号
Tableview not receiving signals from Driver
我有以下 MVVM-C + RxSwift 代码。
问题是 TableView 没有接收到任何信号。当我
调试结果 我可以看到 API 调用返回了它应该返回的内容,objects
数组填充了对象,但 tableview 没有显示任何结果。这是控制台输出:
2018-11-13 16:12:08.107: searchText -> Event next(qwerty)
Search something: qwerty
2018-11-13 16:12:08.324: viewModel.data -> Event next([])
会不会是tableview本身?自定义单元格设置可能有误?
ViewController.swift:
tableView = UITableView(frame: self.view.frame)
tableView.delegate = nil
tableView.dataSource = nil
tableView.register(SearchResultCell.self, forCellReuseIdentifier: "SearchResultCell")
viewModel.data
.debug("viewModel.data", trimOutput: false)
.drive(tableView.rx.items(cellIdentifier: "SearchResultCell")) { row, object, cell in
cell.name.text = object.name
cell.something.text = object.something
}
.disposed(by: disposeBag)
ViewModel.swift:
let disposeBag = DisposeBag()
var searchText = BehaviorRelay(value: "something to search for")
lazy var data: Driver<[Object]> = {
return self.searchText.asObservable()
.debug("searchText", trimOutput: false)
.throttle(0.3, scheduler: MainScheduler.instance)
.distinctUntilChanged()
.flatMapLatest(searchSomething)
.asDriver(onErrorJustReturn: [])
}()
func searchSomething(query: String) -> Observable<[Object]> {
print("Search something: \(query)")
let provider = MoyaProvider<APIService>()
var objects = [Object]()
provider.rx.request(.search(query: query)).subscribe { event in
switch event {
case let .success(response):
do {
let responseJSON: NSDictionary = try (response.mapJSON() as? NSDictionary)!
objects = self.parse(json: responseJSON["results"] as Any)
} catch(let error) {
print(error)
}
break
case let .error(error):
print(error)
break
}
}
.disposed(by: disposeBag)
let result: Observable<[Object]> = Observable.from(optional: objects)
return result
}
- 使用
flatMap
时,您不想创建嵌套订阅。您将创建一个 Observable
的 return 预期结果,flatMap 将负责订阅它。在目前的情况下,searchSomething
将始终 return 一个空数组,因为 Observable.from(optional: objects)
将在请求有机会完成之前被调用。
- 从 Moya 10.0 版开始,提供商将 cancel the requests it created when deallocated。在这里,它将在执行退出时被释放
searchSomething
,因此网络请求将没有时间完成。将提供者的声明移动到视图模型级别可以解决此问题。
此处searchSomething(query: String) -> Observable<[Object]>
重写。
let provider = MoyaProvider<APIService>()
func searchSomething(query: String) -> Observable<[Object]> {
print("Search something: \(query)")
return provider.rx.request(.search(query: query)).map { (response) -> [Object] in
let responseJSON: NSDictionary = try (response.mapJSON() as? NSDictionary)!
return self.parse(json: responseJSON["results"] as Any)
}
}
不是在订阅中进行转换,而是在 map
中完成,每个 next
事件都会调用它,并传递与事件关联的值。
我有以下 MVVM-C + RxSwift 代码。
问题是 TableView 没有接收到任何信号。当我
调试结果 我可以看到 API 调用返回了它应该返回的内容,objects
数组填充了对象,但 tableview 没有显示任何结果。这是控制台输出:
2018-11-13 16:12:08.107: searchText -> Event next(qwerty)
Search something: qwerty
2018-11-13 16:12:08.324: viewModel.data -> Event next([])
会不会是tableview本身?自定义单元格设置可能有误?
ViewController.swift:
tableView = UITableView(frame: self.view.frame)
tableView.delegate = nil
tableView.dataSource = nil
tableView.register(SearchResultCell.self, forCellReuseIdentifier: "SearchResultCell")
viewModel.data
.debug("viewModel.data", trimOutput: false)
.drive(tableView.rx.items(cellIdentifier: "SearchResultCell")) { row, object, cell in
cell.name.text = object.name
cell.something.text = object.something
}
.disposed(by: disposeBag)
ViewModel.swift:
let disposeBag = DisposeBag()
var searchText = BehaviorRelay(value: "something to search for")
lazy var data: Driver<[Object]> = {
return self.searchText.asObservable()
.debug("searchText", trimOutput: false)
.throttle(0.3, scheduler: MainScheduler.instance)
.distinctUntilChanged()
.flatMapLatest(searchSomething)
.asDriver(onErrorJustReturn: [])
}()
func searchSomething(query: String) -> Observable<[Object]> {
print("Search something: \(query)")
let provider = MoyaProvider<APIService>()
var objects = [Object]()
provider.rx.request(.search(query: query)).subscribe { event in
switch event {
case let .success(response):
do {
let responseJSON: NSDictionary = try (response.mapJSON() as? NSDictionary)!
objects = self.parse(json: responseJSON["results"] as Any)
} catch(let error) {
print(error)
}
break
case let .error(error):
print(error)
break
}
}
.disposed(by: disposeBag)
let result: Observable<[Object]> = Observable.from(optional: objects)
return result
}
- 使用
flatMap
时,您不想创建嵌套订阅。您将创建一个Observable
的 return 预期结果,flatMap 将负责订阅它。在目前的情况下,searchSomething
将始终 return 一个空数组,因为Observable.from(optional: objects)
将在请求有机会完成之前被调用。 - 从 Moya 10.0 版开始,提供商将 cancel the requests it created when deallocated。在这里,它将在执行退出时被释放
searchSomething
,因此网络请求将没有时间完成。将提供者的声明移动到视图模型级别可以解决此问题。
此处searchSomething(query: String) -> Observable<[Object]>
重写。
let provider = MoyaProvider<APIService>()
func searchSomething(query: String) -> Observable<[Object]> {
print("Search something: \(query)")
return provider.rx.request(.search(query: query)).map { (response) -> [Object] in
let responseJSON: NSDictionary = try (response.mapJSON() as? NSDictionary)!
return self.parse(json: responseJSON["results"] as Any)
}
}
不是在订阅中进行转换,而是在 map
中完成,每个 next
事件都会调用它,并传递与事件关联的值。