Search code examples
iosswiftuitableviewrx-swiftmoya

Repeat request in RxMoya


I'm using the latest version of Moya with RxSwift and I've encountered a logical issue for which I can't find a solution, at the moment.

Let's say that I have a UITableViewController with a ViewModel that implements the following interface:

protocol ListViewModelType {

    var items: Observable<[Item]> { get }

}

The items property is implemented as (using EVReflection):

var items: Observable<[Therapy]> {
        get {
            let provider = RxMoyaProvider<ItemService>()
            return provider
                .request(.all)
                .map(toArray: Item.self)
        }
    }

In the viewDidLoad method of the UITableViewController, I have set up a binding between the items property and the tableView via the following code:

self.viewModel.items
            .bind(to: tableView.rx.items(cellIdentifier: cellIdentifier, cellType: cellType)) { row, element, cell in
                // cell configuration code
            }
            .disposed(by: self.disposeBag)

Now, I would like to refresh the content of the UITableView to reflect changes that the user has done through other parts of the app. Considering that the RxMoyaProvider returns an Observable, this should be easily done through another value emitted by the Observable, but I don't know how to communicate to the provider that it should refresh the content from the server and put it into the same Observable.

Am I missing something here? Is there a more recommended way to bind a UITableView to a list of objects coming from a RxMoyaProvider?


Solution

  • You have to reload our Moya request. this is a bit hacky but i guess you get the hint.

    let didAppear = Variable(true)
    override func viewDidAppear(_ animated: Bool) {
        didAppear.value = true
    }
    
    override func viewDidLoad(){
        self.didAppear.flatMap{ _ in self.viewModel.items}
            .bind(to: tableView.rx.items(cellIdentifier: cellIdentifier, cellType: cellType)) { row, element, cell in
                // cell configuration code
            }
            .disposed(by: self.disposeBag)
    }
    

    alternatively you could redesign our architecture with a offline-first principle

    enter image description here