RxCocoa-observable испускает новые данные из API, но tableview.rx.items не показывает новые данные - PullRequest
0 голосов
/ 17 октября 2018

Я новичок как в RxSwift, так и в RxCocoa.

У меня есть работающий REST-сервис на локальном компьютере, который возвращает объект Movie для заданного "id".

На моей раскадровке есть tableView(UITableView), который имеет пользовательские ячейки (MovieCell).Каждая ячейка фильма имеет UILabel с именем «nameTextLabel».У меня также есть textField для получения запрошенного movie.id от пользователя.

Я пытаюсь показать movie.title в каждой строке моего tableView.

import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {

@IBOutlet var textField: UITextField!
@IBOutlet var tableView: UITableView!
let bag = DisposeBag()

override func viewDidLoad() {
    super.viewDidLoad()
    configureReactiveBinding()
}
private func configureReactiveBinding() {
    textField.rx.text.asObservable()
        .map { ($0 == "" ? "15" : $0!).lowercased() }
        .map { GetMovieByIdRequest(id: $0) }
        .flatMap { request -> Observable<Movie> in
            return ServiceManager.instance.send(apiRequest: request)
        }
    .debug("movie")
// output:
//2018-10-17 16:13:49.320: movie -> subscribed
//2018-10-17 16:13:49.401: movie -> Event next(MovieAdvisor.Movie)
//2018-10-17 16:13:52.021: movie -> Event next(MovieAdvisor.Movie)
    .toArray()
    .debug("tableView")
// output:
//2018-10-17 16:13:49.318: tableView -> subscribed

        .bind(to: tableView.rx.items(cellIdentifier: "movie_cell", cellType:MovieCell.self)) { index, model, cell in
            cell.nameTextLabel.text = model.title
        }
        .disposed(by: bag)
}

}

Каждый раз, когда textLabel изменяетсяпечатается новый movie.id, но tableView не показывает никаких данных - даже с начальным значением (когда textField равно "").

Есть идеи, как это исправить?

Последобавив строки debug (), я понял, что tableView подписывается только один раз, и никакие последующие события не вызывают tableView.Что я должен делать?Код загружен на GitHub github

Ответы [ 2 ]

0 голосов
/ 17 октября 2018

Проблема в вашем toArray() операторе.Этот оператор ожидает, пока последовательность не завершит , а затем выдает всю последовательность в виде одного массива.Ваша последовательность не завершится до тех пор, пока вы не выйдете из контроллера вида.

Замените его на .map { [$0] }, и фильм будет показан.Вы должны спросить себя, почему ваша конечная точка возвращает только один фильм, а не массив фильмов.

0 голосов
/ 17 октября 2018

Попробуйте заменить

`a.subscribe(onNext: {movie in
    print(movie.title)
})
.disposed(by: bag)

на .observeOn(MainScheduler.instance) и посмотрите, поможет ли это.

Возможно, переместите .toArray() сразу после ServiceManager.instance.send(apiRequest: request).

Также вы можете добавить *.debug("my custom message")* после каждого оператора RxSwift, чтобы увидеть, выполняется ли он.

Кстати, я бы порекомендовал использовать для этого инфраструктуру RxDataSources, а не голый RxCocoa.

...