使用Moya+ReactiveCocoa进行网络请求的MVVM

此篇紧接着上篇 使用Moya+ReactiveCocoa 进行网络请求 http://www.jianshu.com/p/7bf635577900

**
 *  登录viewModel
 */
struct LoginViewModel {
    /// 账号
    let account = MutableProperty<String>("")
    /// 密码
    let password = MutableProperty<String>("")
    /// 是否可点击
    let inputIsValid = MutableProperty<Bool>(true)
    //Action,接受一个类型Void,返回新的类型Bool,并且附带NetRequestError这个错误类型
    lazy var loginAction: Action<Void, Bool, NetRequestError> = {
        let action: Action<Void, Bool, NetRequestError> = Action(enabledIf: self.inputIsValid, {  _ in
//有时我们只需要网络返回的数据的最外面一层来判断请求结果

//   所以上一篇的Comminfo  Model在这里就有用了
            let signal: SignalProducer<Comminfo?, NetRequestError> = NetHelper.shareInstance.requestProvider.request(RequestAPI.login(account: self.account.value, pwd: self.password.value))
                .mapResponseToObject(Comminfo)
            
            return signal
                .map({ commonInfo in
                    guard let common = commonInfo else {
                        return false
                    }
                    return true
                })
        })
        return action
    }()
    
    
    init() {
        resetUIValues()
//这个意思是:account与password的值和inputIsValid相关联
//当account的个数是11位,并且password的个数在6到16位之间
        self.inputIsValid <~ combineLatest(account.producer, password.producer)
            .map { $0.0.characters.count == 11 && (6...16) ~= $0.1.characters.count }
    }
}
extension LoginViewModel {
    
    private func resetUIValues() {
        account.value = ""
        password.value = ""
    }

}

登录控制器VC

class LoginViewController: UIViewController {

    var viewModel = LoginViewModel()
    private lazy var loginView: LoginView = LoginView()
    这里一定要注意---一定要申明这个属性的时候,不要申明成可选的!!!!
    var loginAction:CocoaAction!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setUpUI()
        bindViewModel()
    }
}
extension LoginViewController {
    private func setUpUI() {
        title = "登录"
        loginView.frame = view.bounds
        view.addSubview(loginView)
    }
    
    //绑定view和viewModel
    private func bindViewModel() {
        viewModel.account <~ loginView.accountTf.rac_textSignalProducer()
        viewModel.password <~ loginView.passwordTf.rac_textSignalProducer()
        //绑定view上按钮的可操作和颜色与viewModel的属性
        viewModel.inputIsValid.producer
            .observeOn(UIScheduler())
            .startWithNext { [weak self] inputIsVlid in
                self?.loginView.loginBtn.enabled = inputIsVlid
                self?.loginView.loginBtn.backgroundColor = inputIsVlid ? UIColor(hexString: "ff5b48") : UIColor.grayColor()
        }
        //绑定view上按钮的action,与viewModel的Action相关联
        loginAction = CocoaAction(viewModel.loginAction, input: ())
        loginView.loginBtn.addTarget(loginAction, action: CocoaAction.selector, forControlEvents: .TouchUpInside)
        //发送通知---即信息
        viewModel.loginAction.events.observeOn(UIScheduler())
            .observeNext ({ event in
                switch event {
                case let .Next(_):
                    print("登陆成功")
                case .Failed(let error):
                    print("+++\(error)")
                default:
                    break
                }
            })
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 175,534评论 25 709
  • 转载:http://ios.jobbole.com/83602/ 最近工作比较忙,但还是出来更新博客了,今天给大家...
    VV木公子阅读 9,524评论 3 28
  • 四天时间带你领略从无到有的创造力 广东沿海经济带的创意之旅——深圳香港澳门珠海 第一天 在深圳罗湖口岸过关 (记得...
    木子尘阅读 4,258评论 0 4
  • 孩子,有多长时间没有听到你喊爸爸妈妈了,我现在也不知道如何与你沟通。自己内心苦闷,一边心疼你的现状,一边自己也疼苦...
    山东笑笑爸阅读 2,905评论 0 0
  • 同学发了个朋友圈玩个幼稚游戏。结果答错题,头像换成了青蛙。她也换了,另一个同学也换了。三只青蛙在宿舍群里呱呱,傻傻...
    abdec69fff26阅读 1,306评论 0 0