Выполнение вызова API на View DidLoad с MVVM swift - PullRequest
1 голос
/ 17 октября 2019

У меня есть приложение, в котором я хочу сделать вызов API после пробуждения экрана во ViewController. По сути, я использую Universal Link для активации ViewCOntroller, и когда он отображает UIViewController, я хочу сделать вызов API на основе полученных данных. Я в настоящее время использую архитектуру MVVM, и я добавил свой код ниже

Моя ViewModel

    class EmailVerificationViewModel: ViewModel, ViewModelType {

        struct Input {
            let editEmailTrigger: Driver<Void>
        }

        struct Output {

        }

        let routeManager: BehaviorRelay<RouteMatchResult?>
        let currentEmail: BehaviorRelay<String?>

        init(routeManager: RouteMatchResult?, provider: Api, currentEmail: String?) {
            self.routeManager = BehaviorRelay(value: routeManager)
            self.currentEmail = BehaviorRelay(value: currentEmail)
            super.init(provider: provider)
        }

        func transform(input: Input) -> Output {

         // THE CALL I WANT TO MAKE
            routeManager.errorOnNil().asObservable()

            .flatMapLatest { (code) -> Observable<RxSwift.Event<User>> in
            log("=========++++++++++++==========")
//            guard let code = code else {return}
            let params = code.values
                let challengeId = Int(params["xxx"] as? String ?? "0")
                let login = LoginResponseModel(identifier: params["xxxx"] as? String, key: params["xxxxxx"] as? String, oth: params["xxxxx"] as? String, id: 0, challengeId: challengeId)

            return self.provider.postVerifyApp(challengeId: login.challengeId!, oth: login.oth!, identifier: login.identifier!)
            .trackActivity(self.loading)
            .trackError(self.error)
            .materialize()
        }.subscribe(onNext: { [weak self] (event) in
            switch event {
            case .next(let token):
                log(token)
                AuthManager.setToken(token: token)
//                self?.tokenSaved.onNext(())
            case .error(let error):
                log(error.localizedDescription)
            default: break
            }
        }).disposed(by: rx.disposeBag)

            return Output()
        }
    }

Мой Viewcontroller

override func bindViewModel() {
        super.bindViewModel()
        guard let viewModel = viewModel as? EmailVerificationViewModel else { return }

        let input = EmailVerificationViewModel.Input(editEmailTrigger: editEmailBtn.rx.tap.asDriver())
        let output = viewModel.transform(input: input)

        viewModel.loading.asObservable().bind(to: isLoading).disposed(by: rx.disposeBag)
        viewModel.parsedError.asObservable().bind(to: error).disposed(by: rx.disposeBag)

        isLoading.asDriver().drive(onNext: { [weak self] (isLoading) in
            isLoading ? self?.startAnimating() : self?.stopAnimating()
        }).disposed(by: rx.disposeBag)


        error.subscribe(onNext: { [weak self] (error) in
            var title = ""
            var description = ""
            let image = R.image.icon_toast_warning()
            switch error {
            case .serverError(let response):
                title = response.message ?? ""
            }
            self?.view.makeToast(description, title: title, image: image)
        }).disposed(by: rx.disposeBag)
    }

так, как я могу сделать вызов по комментарию, как THE CALL I WANT TO MAKE, как только приложение ловит универсальную ссылку и загружается. По сути, вызов API для viewDidLoad

1 Ответ

0 голосов
/ 18 октября 2019

Код в вашем примере был намного больше, чем нужно, чтобы ответить на вопрос. Вот как вы делаете сетевой вызов на viewDidLoad:

class ViewController: UIViewController {

    var viewModel: ViewModel!

    private let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()

        let input = ViewModel.Input()
        let output = viewModel.transform(input: input)
        output.viewData
            .bind(onNext: { viewData in
                // setup the view with viewData
            })
            .disposed(by: disposeBag)
    }
}

class ViewModel {
    struct Input { }
    struct Output {
        let viewData: Observable<ViewData>
    }

    init(api: API) {
        self.api = api
    }

    func transform(input: Input) -> Output {
        let viewData = api.networkCall()
            .map { ViewData(from: $0) }
        return Output(viewData: viewData)
    }

    let api: API
}
...