Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rx swift 如何在RxSwift中设置属性并从UIAlertController获取回调?_Rx Swift_Uialertcontroller - Fatal编程技术网

Rx swift 如何在RxSwift中设置属性并从UIAlertController获取回调?

Rx swift 如何在RxSwift中设置属性并从UIAlertController获取回调?,rx-swift,uialertcontroller,Rx Swift,Uialertcontroller,我有一个ViewModelType来绑定UIViewController和ViewModel 导入基础 协议视图模型类型{ 关联类型输入 关联类型输出 func变换(输入:输入)->输出 } HomeViewModel符合ViewModelType并定义所需的输入和输出,然后根据输入返回输出 为简单起见,我删除了存储库,并始终返回syncData任务失败 导入基础 导入RxSwift 进口RxCocoa 类HomeViewModel:ViewModelType{ 结构输入{ 让同步数据:驱动程

我有一个ViewModelType来绑定UIViewController和ViewModel

<代码>导入基础 协议视图模型类型{ 关联类型输入 关联类型输出 func变换(输入:输入)->输出 } HomeViewModel符合ViewModelType并定义所需的输入和输出,然后根据输入返回输出

为简单起见,我删除了存储库,并始终返回syncData任务失败

<代码>导入基础 导入RxSwift 进口RxCocoa 类HomeViewModel:ViewModelType{ 结构输入{ 让同步数据:驱动程序 } 结构输出{ 让信息:司机 } func变换(输入:输入)->输出{ 让fetching=input.syncData.flatMapLatest{uu->Driver在 return Observable.from(可选:“选择下面的选项继续”)//服务器将返回此消息。 .delay(.seconds(1),调度程序:MainScheduler.instance) .asDriverOnErrorJustComplete()文件 } 返回输出(消息:获取) } } 我有一个带字符串的alert活页夹

UIAlertController
在单击重试按钮时有一个重试按钮我想从
HomeViewModel的
Input
调用
syncData
,我该怎么做

导入UIKit
导入RxSwift
进口RxCocoa
类HomeViewController:UIViewController{
私有出租dispebag=dispebag()
var viewModel=HomeViewModel()
重写func viewDidLoad(){
super.viewDidLoad()
让ViewDidDisplay=rx.sentMessage(#选择器(UIViewController.ViewDidDisplay(:))
.maptovid()
.asDriverOnErrorJustComplete()文件
//如何合并视图将显示并提醒重试按钮的回调?
让输入=HomeViewModel.input(syncData:ViewDidDisplay)
让输出=viewModel.transform(输入:输入)
输出.message.drive(警报)
.处置(由:处置人)
}
var警报:活页夹{
返回活页夹(self){(vc,消息)在
let alert=UIAlertController(标题:“同步失败!”,
讯息:讯息,,
preferredStyle:。警报)
let okay=UIAlertAction(标题:“重试”,样式:。默认值,处理程序:{uu}in
//如何调用输入的syncData?
})
让解雇=UIAlertAction(标题:“解雇”,
样式:UIAlertAction.style.cancel,
处理程序:无)
警报。添加操作(正常)
警报。添加操作(解除)
vc.present(警报、动画:true、完成:nil)
}
} 
}

首先,您应该使用一些协调器来调用推送/呈现控制器。 并生成表示告警的函数

例如:

类路由器{
私有let rootViewController:UIViewController
让retryAction=PublishSubject()
func showGalleryAlert(){
let alert=UIAlertController(标题:“您的标题”,消息:“您的消息”,首选样式:。警报)
let settings=UIAlertAction(标题:“名称操作”,样式:。默认值){
//将您的操作发送到此处以发布主题
self.retryAction.send()
}
let cancel=UIAlertAction(标题:“取消”,样式:。取消,处理程序:nil)
alert.addAction(取消)
alert.addAction(设置)
rootViewController.present(警报,动画:true)
}}
然后你需要将这个路由器注入你的ViewModel并收听这个公开主题

或者您可以使用单个/可能的函数,下面是一个如何使用它的小示例:

  public func openList() -> Maybe<Void> {          
        return .create { observer -> Disposable in
              let alert = UIAlertController(title: "Your Title", message: "YourMessage", preferredStyle: .alert)

      let settings = UIAlertAction(title: "Name Action", style: .default) { _ in
        // send here your action
        observer.send() 
     }
      let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
      alert.addAction(cancel)
      alert.addAction(settings)
      rootViewController.present(alert, animated: true)
            return Disposables.create {
                DispatchQueue.main.async {
                    vc.dismiss(animated: true, completion: nil)
                }
            }
        }
    }
public func openList()->可能{
return.在中创建{observer->Disposable
让alert=UIAlertController(标题:“您的标题”,消息:“您的消息”,首选样式:。alert)
let settings=UIAlertAction(标题:“名称操作”,样式:。默认值){
//把你的行动传过来
观察员发送()
}
let cancel=UIAlertAction(标题:“取消”,样式:。取消,处理程序:nil)
alert.addAction(取消)
alert.addAction(设置)
rootViewController.present(警报,动画:true)
归还一次性物品。创建{
DispatchQueue.main.async{
vc.discouse(动画:true,完成:nil)
}
}
}
}
并通过ViewModel进行处理


p.S:您应该在ViewModel中的输入主题上使用,而不是在驱动程序上使用。驱动程序必须仅适用于输出等视图。

有两种情况需要使用主题,一种是将非RxCode转换为RxCode(如使UIAlertAction反应),另一种是必须创建循环(如将视图模型的输出反馈回自己的输入)

如果你发现自己做了很多事情,那么你可能需要考虑制作多个视图模型。 您还将注意到,我将警报的创建作为自己的、独立的协调函数。这样,它可以在多个地方使用。如果需要,可以对传递到

flatMapFirst
的闭包执行相同的操作

class HomeViewModel {

    struct Input {
        let syncData: Observable<Void>
        let retry: Observable<Void>
    }

    struct Output {
        let message: Observable<String>
    }

    func transform(input: Input) -> Output {
        let fetching = Observable.merge(input.syncData, input.retry)
            .flatMapLatest { _ -> Observable<String> in
                return Observable<String>.from(optional: "Choose below options to proceed") // This message will be returned by server.
                    .delay(.seconds(1), scheduler: MainScheduler.instance)
        }
        return Output(message: fetching)
    }
}

class HomeViewController: UIViewController {

    private let disposeBag = DisposeBag()

    var viewModel = HomeViewModel()

    override func viewDidLoad() {
        super.viewDidLoad()

        let viewDidAppear = rx.sentMessage(#selector(UIViewController.viewDidAppear(_:)))
            .mapToVoid()

        let retry = PublishSubject<Void>()

        let input = HomeViewModel.Input(syncData: viewDidAppear, retry: retry.asObservable())
        let output = viewModel.transform(input: input)

        output.message
            .flatMapFirst { [weak self] (message) -> Observable<Void> in
                let (alert, trigger) = createAlert(message: message)
                self?.present(alert, animated: true)
                return trigger
            }
            .subscribe(retry)
            .disposed(by: disposeBag)
    }
}

func createAlert(message: String) -> (UIViewController, Observable<Void>) {
    let trigger = PublishSubject<Void>()
    let alert = UIAlertController(title: "Sync failed!",
                                  message: message,
                                  preferredStyle: .alert)
    let okay = UIAlertAction(title: "Retry", style: .default, handler: { _ in
        trigger.onNext(())
        trigger.onCompleted()
    })
    let dismiss = UIAlertAction(title: "Dismiss",
                                style: UIAlertAction.Style.cancel,
                                handler: nil)

    alert.addAction(okay)
    alert.addAction(dismiss)
    return (alert, trigger)
}
类HomeViewModel{
结构输入{
让同步数据:可观察
让我们重试:可观察
}
结构输出{
让信息:可观察
}
func变换(输入:输入)->输出{
let fetching=Observable.merge(input.syncData,input.retry)
.flatmap最新的{uu->在
return Observable.from(可选:“选择下面的选项继续”)//服务器将返回此消息。
.delay(.seconds(1),调度程序:MainScheduler.instance)
}
返回输出(消息:获取)
}
}
类HomeViewController:UIViewController{
私有出租dispebag=dispebag()
var viewModel=HomeViewModel()
重写func viewDidLoad(){
超级视图
class HomeViewModel {

    struct Input {
        let syncData: Observable<Void>
        let retry: Observable<Void>
    }

    struct Output {
        let message: Observable<String>
    }

    func transform(input: Input) -> Output {
        let fetching = Observable.merge(input.syncData, input.retry)
            .flatMapLatest { _ -> Observable<String> in
                return Observable<String>.from(optional: "Choose below options to proceed") // This message will be returned by server.
                    .delay(.seconds(1), scheduler: MainScheduler.instance)
        }
        return Output(message: fetching)
    }
}

class HomeViewController: UIViewController {

    private let disposeBag = DisposeBag()

    var viewModel = HomeViewModel()

    override func viewDidLoad() {
        super.viewDidLoad()

        let viewDidAppear = rx.sentMessage(#selector(UIViewController.viewDidAppear(_:)))
            .mapToVoid()

        let retry = PublishSubject<Void>()

        let input = HomeViewModel.Input(syncData: viewDidAppear, retry: retry.asObservable())
        let output = viewModel.transform(input: input)

        output.message
            .flatMapFirst { [weak self] (message) -> Observable<Void> in
                let (alert, trigger) = createAlert(message: message)
                self?.present(alert, animated: true)
                return trigger
            }
            .subscribe(retry)
            .disposed(by: disposeBag)
    }
}

func createAlert(message: String) -> (UIViewController, Observable<Void>) {
    let trigger = PublishSubject<Void>()
    let alert = UIAlertController(title: "Sync failed!",
                                  message: message,
                                  preferredStyle: .alert)
    let okay = UIAlertAction(title: "Retry", style: .default, handler: { _ in
        trigger.onNext(())
        trigger.onCompleted()
    })
    let dismiss = UIAlertAction(title: "Dismiss",
                                style: UIAlertAction.Style.cancel,
                                handler: nil)

    alert.addAction(okay)
    alert.addAction(dismiss)
    return (alert, trigger)
}