swift – 如何在ReactiveCocoa 3和4中进行基本绑定

前端之家收集整理的这篇文章主要介绍了swift – 如何在ReactiveCocoa 3和4中进行基本绑定前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我最近一直在阅读Reactive Cocoa v3,我正在努力只是设置基本的东西.我已经阅读了更新日志,测试,几个问题和Colin Eberhardt关于这个问题的文章.但是,我仍然缺少基本绑定的例子.

假设我有一个应用程序显示当天的菜单.该应用程序正在使用RAC3和MVVM模式.

模型(菜单)

该模型有一个简单的方法获取今天的菜单.至于现在,这不要做任何网络请求,它基本上只是创建一个模型对象. mainCourse属性是一个String.

class func fetchTodaysMenu() -> SignalProducer<Menu,NoError> {
    return SignalProducer {
        sink,dispoable in
            let newMenu = Menu()
            newMenu.mainCourse = "Some meat"
            sendNext(sink,newMenu)
            sendCompleted(sink)
    }
}

viewmodel(Menuviewmodel)

视图模型暴露了不同的String变量,让视图控制器显示菜单.我们只需添加一个显示菜单属性.

var mainCourse = MutableProperty("")

我们为此属性添加绑定:

self.mainCourse <~ Menu.fetchTodaysMenu()
    |> map { menu in
        return menu.mainCourse!
    }

ViewController(MenuViewController)

最后但并非最不重要的是,我想提出这个主要课程.我会为此添加一个UILabel.

var headline = UILabel()

最后我想通过观察我的视图模型来设置该UILabel的text属性.就像是:

self.headline.text <~ viewmodel.headline.producer

不幸的是不行.

问题

> fetchTodaysMenu()方法返回一个SignalProducer< Menu,NoError>,但是如果我想要这种方法返回SignalProducer< Menu,NSError>代替?这将使我的视图模型中的绑定失败,因为该方法现在可能会返回一个错误.我该如何处理?
>如上所述,我的视图控制器中的当前绑定不起作用.我一直在玩,创建一个代表UILabel的文本属性的MutableProperty,但是我从来没有这样做.我也觉得笨拙或冗长地为每个要绑定的属性创建额外的变量.这在RAC2中不是必需的.我有意试图避免使用DynamicProperty,但也许我不应该我基本上只是想找到正确的方式做RAC(self.headline,text)= RACObserve(self.viewmodel,mainCourse);.

任何其他反馈/指导如何使这个基本设置受到高度赞赏.

所以,在写这个问题之后,Colin Eberhardt做了他的RAC3博客文章系列的第3部分,其中包括一个使用MVVM和RAC3的有趣且非常相关的例子.该帖子可以发现 here和源代码 here.

根据他的工作,我设法回答了我自己的问题:

>通过略微不同的方法,我可以使fetchTodaysMenu()返回一个SignalProducer< Menu,NSError>按需要以下是我在视图模型中做的事情:

MenuService.fetchTodaysMenu()
    |> observeOn(QueueScheduler.mainQueueScheduler)
    |> start(next: { response in
        self.mainCourse.put(response.mainCourse!)
    },error: {
        println("Error \($0)")
    })

>似乎没有UIKit绑定,而是RAC3 beta 4. Colin自己做了一些UIKit扩展来帮助他做这些绑定我也在寻找.这些可以在here找到.将它们添加到我的项目中,使得能够完全按照我想要的:

self.mainCourse.rac_text <~ self.viewmodel.mainCourse

更新2015年5月25日

在ReactiveCocoa 3工作之后,我再次回答1).通过使用catch,可以以更加声明的方式来做到这一点.我最终实现了一个小帮手功能

public func ignoreError<T: Any,E: ErrorType>(signalProducer: SignalProducer<T,E>) -> SignalProducer<T,NoError> {
    return signalProducer
        |> catch { _ in
            SignalProducer<T,NoError>.empty
        }
}

函数将任何NSError转换为NoError,使得可以按照我想要的方式进行绑定:MenuService.fetchTodaysMenu()|> ignoreError.

我开始采购我的项目,因为这可能是其他人研究ReactiveCocoa 3.0的好起点:
https://github.com/s0mmer/TodaysReactiveMenu

2016年3月5日更新

正如注释中所强调的,自Swift 2以来,ignoreError函数现在将如下所示:

public func ignoreError() -> SignalProducer<Value,NoError> {
    return flatMapError { _ in
        SignalProducer<Value,NoError>.empty
    }
}

此外,还建立了一个名为Rex的扩展库,其中添加了类似的内容.

原文链接:https://www.f2er.com/swift/318921.html

猜你在找的Swift相关文章