我有以下 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
返回预期结果,flatMap 将负责订阅它。在目前的情况下,searchSomething
将始终返回一个空数组,如Observable.from(optional: objects)
将在请求有机会完成之前调用。 - 从 Moya 10.0 版开始,提供商将 cancel the requests it created when deallocated .在这里,它将在执行退出时被释放
searchSomething
,因此网络请求将没有时间完成。将提供者的声明移至 View 模型级别可解决此问题。
这是 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
都会调用一次事件,传递与事件关联的值。
关于ios - Tableview 未收到来自驱动程序的信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53295891/