Ste*_*mer 10 reactive-cocoa swift reactive-cocoa-3
我最近一直在阅读ReactiveCocoa v3,而我正在努力设置基本的东西.我已经阅读了变更日志,测试,少数SO问题和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()
最后我想text通过观察我的视图模型来设置该UILabel 的属性.像这样的东西:
self.headline.text <~ viewModel.headline.producer
遗憾的是,这不起作用.
问题
fetchTodaysMenu()返回一个SignalProducer<Menu, NoError>,但是如果我希望这个方法返回一个SignalProducer<Menu, NSError>而不是呢?这将使我的视图模型中的绑定失败,因为该方法现在可能会返回错误.我该如何处理?MutableProperty代表text属性的东西UILabel,但我从来没有做对.我还认为必须为我想要绑定的每个属性创建额外的变量,感觉笨拙或冗长.RAC2不需要这样做.我故意也试图避免使用DynamicProperty,但也许我不应该?我基本上只想找到正确的做法RAC(self.headline, text) = RACObserve(self.viewModel, mainCourse);.有关如何进行此基本设置的任何其他反馈/指导非常感谢.
Ste*_*mer 13
所以,在写完这个问题之后,Colin Eberhardt在他的RAC3博客文章系列中做了第3部分,其中包括一个使用MVVM和RAC3的有趣且非常相关的例子.帖子可以在这里找到,源代码在这里.
根据他的工作,我设法回答了我自己的问题:
通过略微不同的方法,我能够按需要进行fetchTodaysMenu()返回SignalProducer<Menu, NSError>.以下是我在视图模型中的操作方式:
MenuService.fetchTodaysMenu()
    |> observeOn(QueueScheduler.mainQueueScheduler)
    |> start(next: { response in
        self.mainCourse.put(response.mainCourse!)
    }, error: {
        println("Error \($0)")
    })
似乎UIKit从RAC3测试版4开始就没有任何绑定.科林UIKit自己做了一些扩展,以帮助他制作我正在寻找的这些绑定.这些可以在这里找到.将它们添加到我的项目中,使我能够完全按照自己的意愿行事:
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的扩展库,其中添加了类似的内容.
| 归档时间: | 
 | 
| 查看次数: | 3653 次 | 
| 最近记录: |