Как мне выполнить принудительный UIViewController или подарок UIAlertController? - PullRequest
0 голосов
/ 27 мая 2019

После некоторых вызовов API у меня есть проверка, чтобы перейти на другой экран или показать предупреждение на том же экране. В настоящее время я делаю это путем создания наблюдаемой, которая возвращает тип UIViewController , но нажатие UIAlertController вызывает проблемы.

Любые предложения / идеи о том, как это должно быть сделано?

ViewModel.swift

let nextAction = Observable.combineLatest(appVersionOutput, serviceAvailabilityOutput, getLanguagePackOutput,
                                              resultSelector:
        { appVersion, _, _ -> UIViewController in
            if appVersion.currentAppVersion == "1.0.0" {
                let appServiceAvailability = Availability.shared.getAppStatus()
                if appServiceAvailability {
                    return LoginLandingViewController()
                } else {
                    return ServiceMaintenanceViewController()
                }
            } else {
                return UIAlertController()
            }
        })

ViewController.swift

viewModel.output.nextAction
        .subscribe(onNext: { [weak self] screen in
            self?.navigationController?.pushViewController(screen, animated: true) 
        }) // PROBLEM FACED: Pushing a UIAlertController
        .disposed(by: disposeBag)

Ответы [ 3 ]

0 голосов
/ 27 мая 2019

Есть несколько вариантов.

Первый вариант - принятие вашей текущей реализации.Вы могли бы передать информацию в дополнение к ViewController в событии onNext наблюдаемой nextAction, которая расскажет, как показать VC.

Например, вы можете создать ассоциированное перечисление

// you can call it NextAction, Action etc
enum PresentationType {
    case
    push(UIViewController),
    present(UIViewController)
}

ииспользуйте его так:

let nextAction = Observable.combineLatest(appVersionOutput, serviceAvailabilityOutput, getLanguagePackOutput,
                                          resultSelector:
    { appVersion, _, _ -> PresentationType in
        if appVersion.currentAppVersion == "1.0.0" {
            let appServiceAvailability = Availability.shared.getAppStatus()
            if appServiceAvailability {
                return .push(LoginLandingViewController())
            } else {
                return .push(ServiceMaintenanceViewController()) // use .present if should present modally
            }
        } else {
            return .present(UIAlertController())
        }
})

// somewhere in viewController

viewModel.output.nextAction
        .subscribe(onNext: { [weak self] action in
        switch action {
            case .push(let vc):
                self?.navigationController?.pushViewController(vc, animated: true)
            case .present(let vc):
                self?.present(vc, animated: true, completion: nil)

        })
        .disposed(by: disposeBag)

Второй (и в некотором смысле более гибкий и тестируемый) вариант - создать отдельный класс Router, который отвечает за создание и отображение следующих экранов (с функциями showLogin).showAlert и т. Д.)Маршрутизатор может быть напрямую введен во ViewModel, и вы можете вызвать маршрутизатор для отображения следующих экранов, например, в событиях do (onNext) в ваших наблюдаемых объектах.

0 голосов
/ 27 мая 2019

Вы можете посмотреть ключевое слово is, которое позволяет вам проверять тип объекта. Подробнее о ключевом слове .В качестве альтернативы можно использовать type(of: object) и сравнить с UIAlertViewController.self

Поскольку вам нужно представить UIAlertViewController, а не выдвигать его, используйте if и else с указанным выше, чтобы представить, если тип равен UIAlertViewControllerи нажмите, если не так.NB. Нет необходимости проверять UIViewController, поскольку все они.

0 голосов
/ 27 мая 2019

Вы можете проверить класс, используя classForCoder

viewModel.output.nextAction
    .subscribe(onNext: { [weak self] screen in
        if String(describing: screen.classForCoder) == "UIAlertController" {
            //present
            self?.present(screen, animated: true, completion: nil)
        } else {
            //navigate
            self?.navigationController?.pushViewController(screen, animated: true)
        } 
    }) // PROBLEM FACED: Pushing a UIAlertController
    .disposed(by: disposeBag)
...