如何使用ReactiveCocoa

时间:2015-06-23 14:44:07

标签: ios objective-c iphone swift reactive-cocoa

我想知道从服务器处理无效令牌的正确方法是什么。

  1. 我想到的第一个解决方案是在ViewModel层启动一个事件,在rootViewController导航中监听登录页面。

  2. 第二个解决方案(第一个解决方案有效,但我真的不喜欢事件,我想使用信号而不是事件),在rootViewController中添加一个authenticationViewModel,订阅invalidToken(或者在其中调用logout信号)在rootViewController中查看图层信号,在api调用中触发信号。

  3. 我想问一下,有没有更好的方法来解决这个问题?

1 个答案:

答案 0 :(得分:0)

该示例基于RAC3,我不知道是否是最佳解决方案,但这与我在实验后的结果有关。

我将身份验证令牌作为MutableProperty存储在View Model中,在View Controller中我观察有效和无效的令牌。

这样的事情:

查看型号:

class LoginViewModel {

    let username = MutableProperty<String>("")
    let password = MutableProperty<String>("")
    let authToken = MutableProperty<String>("")
    let invalidToken = MutableProperty<String>("")
    private let _inputValid = MutableProperty(false)

    var action:Action<AnyObject?, String, NSError>?
    var cocoaAction:CocoaAction?

    init() {
       let validation: Signal<String, NoError> -> Signal<Bool, NoError> = map { string in
           return count(string) > 0
       }

       _inputValid <~ combineLatest(
           username.producer
              |> validation,
           password.producer
              |> validation)
        |> map({ user, pass in return user && pass })

        action = Action(enabledIf:_inputValid) { _ in
            return LoginService().login(self.username.value, password: self.password.value) }
        cocoaAction = CocoaAction(action!, input: nil)
        action!.values.observe(next: { self.authToken.put($0) })
        action!.errors.observe(next: { self.invalidToken.put($0)})
   }
}

在ViewController中,您可以观察到authToken和invalidToken:

viewModel.authToken.producer
    |> filter { count($0) > 0 }
    |> start(next: {
        _ in
            // do something in case token is ok 
    })

viewModel.invalidToken.producer
    |> filter { count($0) > 0 }
    |> start(next: {
        _ in
            // do something in case token is NOT ok 
    })

如果您的用户名和密码是文本字段,则可以将输入映射到对应的视图模型,如下所示

viewModel.username <~ userNameTextField.rac_textSignal().toSignalProducer() |> map { $0 as? String ?? "" } |> catch { _ in SignalProducer<String, NoError>.empty }
viewModel.password <~ passwordTextField.rac_textSignal().toSignalProducer() |> map { $0 as? String ?? "" } |> catch { _ in SignalProducer<String, NoError>.empty }