title: Can I use MVVM without data binding?
body: <p>I am trying to use MVVM. Upon reading some blogs on MVVM, I found them using data binding techniques like Rx, KVO, Boxing etc. Following are my classes for validating user using MVVM. I have not put any code for data binding. What I do is simply pass the username and password from viewcontroller to my view model class upon the submit button click. The view model consists all the logic for validation. And at the end, it returns the status to the viewcontroller, depending on which the view controller shows some message. I am wandering is this the way to go or should some data binding be used?</p>
  
  <p>SignUpViewController.swift</p>
  
  <pre><code>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) -&gt; 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)
      }
  }
  </code></pre>
  
  <p>SignUpViewModel.swift</p>
  
  <pre><code>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() -&gt; 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) -&gt; Bool {
          let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}"
          return NSPredicate(format:"SELF MATCHES %@", emailRegEx).evaluate(with: email)
      }
  
      func isValidPhone(phone: String) -&gt; Bool {
          return true
      }
  
      func isBlank(text: String) -&gt; Bool {
          return text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
      }
  
      func isValidPasswordLength(password: String) -&gt; Bool {
          guard password.count &lt; minPasswordLength else {
              return true
          }
          return false
      }
  
      func passwordsMatch(password: String, confirmpassword: String) -&gt; Bool {
          guard password == confirmpassword else {
              return false
          }
          return true
      }
  
      func isNumber(username: String) -&gt; Bool {
          guard let _ = Int(username) else {
              return false
          }
          return true
      }
  }
  </code></pre>
  
  <p>User.swift</p>
  
  <pre><code>import Foundation
  
  struct User {    
      var username: String?
      var password: String?
      var confirmpassword: String?
  }
  </code></pre>