0

This time, I am implementing the screen with RxSwift / MVVM. It's too difficult to implement RxSwift as an MVVM.

What I wanted to ask you was to enter the list screen and get the data. Then it went into the detail screen and changed specific data. And if it go to the list screen, it have to update the data.

I think I can put data in the viewwillappear() of the view controller, and I do not know how to implement the renewal in the view Model, and I do not know if it is right to do this in functional programming like rx.

I defined the viewmodel as follows. The store.getListEventWinning() method is a function that fits data and is delivered in the form of Observable.

enter image description here

Binding was done in view controller as below.

enter image description here

Tae Hun Yu
  • 39
  • 7

1 Answers1

0

You don't give a lot of detail, despite the code you posted. I will address your specific comment, "What I wanted to ask you was to enter the list screen and get the data. Then it went into the detail screen and changed specific data. And if it go to the list screen, it have to update the data."

Using my CLE library (which you can install with cocoapods or SPM) doing this is quite simple.

let change = changeButton.rx.tap
    .flatMapFirst(presentScene(animated: true) {
        DetailViewController.scene { $0.connect() }
    })

Here is a complete example that you can run yourself to see how it works. To run the below, just add XIB files for the two view controllers, and hook up the outlets.

import Cause_Logic_Effect
import RxCocoa
import RxSwift

final class MainViewController: UIViewController {
    @IBOutlet var addButton: UIButton!
    @IBOutlet var tableView: UITableView!
    let disposeBag = DisposeBag()
}

final class DetailViewController: UIViewController {
    @IBOutlet var saveButton: UIButton!
    @IBOutlet var nameField: UITextField!
    let disposeBag = DisposeBag()
}

extension MainViewController {
    func connect() {
        let initial = Observable<[String]>.just([]) // This could be a network request
        let addName = addButton.rx.tap
            .flatMapFirst(presentScene(animated: true) {
                DetailViewController().scene { $0.connect() }
            })

        let state = mainVieweModel(initial: initial, addName: addName)
            .share(replay: 1)

        state
            .bind(to: tableView.rx.items(cellIdentifier: "Cell", cellType: UITableViewCell.self)) { _, name, cell in
                cell.textLabel?.text = name
            }
            .disposed(by: disposeBag)
    }
}

func mainVieweModel(initial: Observable<[String]>, addName: Observable<String>) -> Observable<[String]> {
    enum Input {
        case initial([String])
        case add(String)
    }

    return Observable.merge(
        initial.map { Input.initial($0) },
        addName.map { Input.add($0) }
    )
        .scan(into: [String]()) { state, input in
            switch input {
            case let .initial(value):
                state = value
            case let .add(text):
                state.append(text)
            }
        }
}

extension DetailViewController {
    func connect() -> Observable<String> {
        return saveButton.rx.tap
            .withLatestFrom(nameField.rx.text.orEmpty)
            .take(1)
    }
}

The app delegate looks like this:

import Cause_Logic_Effect
import UIKit

@main
final class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        window = {
            let result = UIWindow(frame: UIScreen.main.bounds)
            result.rootViewController = MainViewController().configure { $0.connect() }
            result.makeKeyAndVisible()
            return result
        }()

        return true
    }
}
Daniel T.
  • 32,821
  • 6
  • 50
  • 72
  • Thank you very much. I watched htis answer so late. Rx/MVVM was hard for me. So I studied Reactorkit and solved its problems. – Tae Hun Yu Oct 17 '22 at 07:59