Как получить значение внутри onNext для доступа к нему снаружи в моем коде - PullRequest
0 голосов
/ 02 августа 2020
• 1000

1 Ответ

0 голосов
/ 03 августа 2020

Вы не должны использовать какие-либо вызовы API для View. Сделайте подписчика вывода на вашей ViewModel и направьте его к вашему представлению.

Пример ViewModel:

import Foundation
import RxSwift
import RxCocoa
import RxDataSources

extension ModelListViewModel {
    enum Sections: SectionModelType {
        typealias Item = ModelDTO
        
        case model(models: [Item])
        
        var items: [Item]  {
            switch self {
            case .model(let models):
                return models
            }
        }
        
        init(original: Sections, items: [Item]) {
            self = original
        }
    }
}

class ModelListViewModel {
    //inputs
    let didLoad = PublishSubject<Void>()
    let modelSelected = PublishSubject<ModelDTO>()
    //outputs
    let sections: Driver<[Sections]>
    
    private let disposeBag = DisposeBag()
    private static var data: [ModelDTO] = {
        var array = [ModelDTO]()
        guard let urlPath = Bundle.main.url(forResource: "seat_medium_quality_m_center", withExtension: "usdz") else {
            return []
        }
        let firstModel = ModelDTO(url: urlPath, modelName: "Seat 1")
        let secondModel = ModelDTO(url: urlPath, modelName: "Seat 2")
        let thirdModel = ModelDTO(url: urlPath, modelName: "Seat 3")
        return [firstModel, secondModel, thirdModel]
    }()
    init(context: ARRouter.ModelListContext) {
        //TODO: Make sections due to responce from BackEnd
        sections = didLoad
            .mapTo([Sections.model(models: ModelListViewModel.data)])
            .asDriver(onErrorDriveWith: .empty())
        
        modelSelected.map { $0.url }
            .bind(to: context.modelSelectedIn)
            .disposed(by: disposeBag)
    }    
 }

Пример ViewController:

import UIKit
import RxSwift
import RxCocoa
import RxDataSources

class ModelListViewController: BaseViewController {
    private struct Cells {
        static let modelListCell = ReusableCell<ModelListCell>(nibName: "ModelListCell")
    }
    
    @IBOutlet private weak var tableView: UITableView! {
        didSet {
            tableView.register(Cells.modelListCell)
            
            viewModel.sections
                .drive(tableView.rx.items(dataSource: dataSource))
                .disposed(by: disposeBag)
            
            tableView.rx
                .modelSelected(ModelDTO.self)
                .bind(to: viewModel.modelSelected)
                .disposed(by: disposeBag)
        }
    }
    private let disposeBag = DisposeBag()
    private let viewModel: ModelListViewModel
    private let dataSource: RxTableViewSectionedReloadDataSource<ModelListViewModel.Sections>
    
    init(viewModel: ModelListViewModel) {
        self.viewModel = viewModel
        self.dataSource = .init(configureCell: { (_, tableView, indexPath, item) -> UITableViewCell in
            let cell = tableView.dequeue(Cells.modelListCell, for: indexPath)
            cell.setup(with: item)
            return cell
        })
        super.init(nibName: "ModelListViewController", bundle: nil)
        
        rx.viewDidLoad
            .bind(to: viewModel.didLoad)
            .disposed(by: disposeBag)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}
...