在调用了一些API之后,我进行了检查,以导航到另一个屏幕或在同一屏幕上显示警报。当前,我通过创建一个返回 UIViewController 类型的可观察对象来实现此目的,但是推送UIAlertController会导致问题。
关于应该如何做的任何建议/想法?
ViewModel.swift
struct Book: Decodable {
let feed: Feed
let entry: [Entry]
init (from decoder :Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
do {
value = try container.decode([Entry].self, forKey: .value)
} catch {
let newValue = try container.decode(Entry.self, forKey: .value)
value = [newValue]
}
}
}
ViewController.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()
}
})
答案 0 :(得分:0)
您可以使用 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)
答案 1 :(得分:0)
有一些选择。
第一个选择是采用当前的实现。 您可以在nextAction的onNext事件中传递ViewView之外的信息,这将告诉您如何显示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)事件中显示下一个屏幕。
答案 2 :(得分:0)
您可以查看is
关键字,该关键字使您可以检查对象类型。 More on is keyword。一种替代方法是使用type(of: object)
并与UIAlertViewController.self
由于您必须提供一个UIAlertViewController
而不是将其推送,因此如果type为UIAlertViewController
,请使用if和else与上面的内容一起呈现,否则请推送。注意:因为它们全部都是,所以不必检查UIViewController。