2017-12-08 21 views
1

MVVMを使用しようとしています。 MVVMでいくつかのブログを読んで、私はRx、KVO、ボクシングなどのデータバインディングテクニックを使ってそれらを見つけました。以下は、MVVMを使ってユーザーを検証するためのクラスです。私はデータバインディングのためのコードを入れていません。私がやっているのは、送信ボタンをクリックしたときにviewcontrollerのユーザ名とパスワードをビューモデルクラスに渡すだけです。ビューモデルは、検証のためのすべてのロジックで構成されています。そして最後に、View Controllerがメッセージを表示するかどうかに応じて、ViewControllerにステータスを返します。私はこれが行く方法ですか、いくつかのデータバインディングを使用する必要がありますか?データバインディングなしでMVVMを使用できますか?

SignUpViewController.swift

import UIKit 

class SignUpViewController: UIViewController { 

    let signupviewmodel = SignUpViewModel() 

    @IBOutlet weak var textFieldUsername: UITextField! 
    @IBOutlet weak var textFieldPassword: UITextField! 
    @IBOutlet weak var textFieldPasswordConfirm: UITextField! 

    @IBAction func initialSignUp(_ sender: Any) { 
     signupviewmodel.updateUsername(username: textFieldUsername.text!) 
     signupviewmodel.updatePassword(password: textFieldPassword.text!) 
     signupviewmodel.updateConfirmPassword(confirmpassword: textFieldPasswordConfirm.text!) 

     switch signupviewmodel.validateUser() { 
      case .Valid: 
       showAlert(title: "Valid", message: "success") 
      case .InValid(let error): 
       showAlert(title: "Error Validation", message: error) 
     } 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 

    func showAlert(title: String, message: String) -> Void { 
     let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert) 
     alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil)) 
     self.present(alert, animated: true, completion: nil) 
    } 
} 

SignUpViewModel.swift

import Foundation 

enum UserValidationState { 
    case Valid 
    case InValid(String) 
} 

class SignUpViewModel { 
    private let minPasswordLength: Int = 6 
    private var user = User() 

    var username: String { 
     return user.username! 
    } 

    var password: String { 
     return user.password! 
    } 

    var confirmpassword: String { 
     return user.confirmpassword! 
    } 
} 

extension SignUpViewModel { 

    func updateUsername(username: String) { 
     user.username = username 
    } 

    func updatePassword(password: String) { 
     user.password = password 
    } 

    func updateConfirmPassword(confirmpassword: String) { 
     user.confirmpassword = confirmpassword 
    } 

    func validateUser() -> UserValidationState { 
     if (username.isBlank || password.isBlank || confirmpassword.isBlank) { 
      return .InValid("Please fill all the fields") 
     } else { 
      if isNumber(username: username) { 
       if isValidPhone(phone: username) { 
        if isValidPasswordLength(password: password) { 
         if passwordsMatch(password: password, confirmpassword: confirmpassword) { 
          return .Valid 
         } 
         return .InValid("Passwords do not match") 
        } 
        return .InValid("Password length doesn't meet criteria") 
       } 
       return .InValid("InValid Phone") 
      } else { 
       if isValidEmail(email: username) { 
        if isValidPasswordLength(password: password) { 
         if passwordsMatch(password: password, confirmpassword: confirmpassword) { 
          return .Valid 
         } 
         return .InValid("Passwords do not match") 
        } 
        return .InValid("Password length doesn't meet criteria") 
       } 
       return .InValid("InValid Email") 
      } 
     } 
    } 

    func isValidEmail(email:String) -> Bool { 
     let emailRegEx = "[A-Z0-9a-z._%+-][email protected][A-Za-z0-9.-]+\\.[A-Za-z]{2,6}" 
     return NSPredicate(format:"SELF MATCHES %@", emailRegEx).evaluate(with: email) 
    } 

    func isValidPhone(phone: String) -> Bool { 
     return true 
    } 

    func isBlank(text: String) -> Bool { 
     return text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty 
    } 

    func isValidPasswordLength(password: String) -> Bool { 
     guard password.count < minPasswordLength else { 
      return true 
     } 
     return false 
    } 

    func passwordsMatch(password: String, confirmpassword: String) -> Bool { 
     guard password == confirmpassword else { 
      return false 
     } 
     return true 
    } 

    func isNumber(username: String) -> Bool { 
     guard let _ = Int(username) else { 
      return false 
     } 
     return true 
    } 
} 

User.swift

import Foundation 

struct User {  
    var username: String? 
    var password: String? 
    var confirmpassword: String? 
} 

答えて

0

データバインディングMVVMの基盤です。したがって、データバインディングは、ビューからすべてのビジネスロジックを保護し、データの送受信と非同期で作業するのに役立ちます。 viewModelに値を渡しても大丈夫ですが、ViewModelsからViewControllersに値を渡す必要がある場合があります。たとえば、いくつかのデータに応答する非同期API要求があります。 MVVMでは、そのデータをViewModelに格納しますが、一部のデータが受信されたことをViewControllerに通知する必要があります。データバインディングは、少ないコード量でこれらのケースを解決するのに役立ちます。はい、コールバックを使用するだけでデータバインディングなしで作業できますが、それは定型コードをたくさん記述する必要があることを意味します。

私はKVO、Rx、Reactiveが難しいと思っています。つまり、複雑なものに徹底することなく、拘束力のある機能だけを提供する単純なライブラリから始めることができます。これらのライブラリチェックアウト:

https://github.com/ReactiveKit/Bond

https://github.com/blendle/Hanson

そして、ちょうどノートのを、あなたはコード化された方法は、より多くのMVP(モデルビュープレゼンター)のようなものです。リアクティブプログラミングが気に入らなければ、その設計アーキテクチャをチェックすることができます。

関連する問題