Как сделать логин используя MVVM? - PullRequest
0 голосов
/ 28 апреля 2018

Я все еще довольно новичок в разработке для iOS и пытаюсь научить себя хорошим методам кодирования и шаблонам проектирования в Swift, начиная с MVVM. Мне нужно передать данные из дескриптора завершения моего класса ServiceCall в мою ViewModel. Мне нужна помощь в понимании того, как я могу это сделать, а также рекомендации по передовым методам использования MVVM в моем коде.

Это то, что я сделал до сих пор:

Модель

struct Login {
  var appVersion: String ?
  var deviceID : String ?
  var deviceOS : String ?
  var password : String ?
  var username : String ?
}

Сервисный звонок / клиент API

class LoginServiceCall : NSObject, URLSessionDelegate {
  let viewResponse = ThrowResponse()
  func requestLogin(request: URLRequest, requestObject: Login, completion: @escaping ([NSDictionary] ? ) -> Void) {
    let searchParams = Login.init(appVersion: requestObject.appVersion, deviceID: requestObject.deviceID, deviceOS: requestObject.deviceOS, password: requestObject.password, username: requestObject.username)
    var request = request
    request.httpMethod = "POST"
    do {
      request.httpBody = try JSONSerialization.data(withJSONObject: searchParams, options: .prettyPrinted)
    } catch let error {
      print(error.localizedDescription)
    }
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    let session = URLSession.shared
    let task = session.dataTask(with: request, completionHandler: {
      data, response, error -> Void in
      do {
        let json = try JSONSerialization.jsonObject(with: data!) as ? Dictionary<String, Any>
        //completion(json!)
        // This is where i would like to pass the dictionary data
      } catch {
        DispatchQueue.main.async {
          self.viewResponse.dismissLoader()
          self.viewResponse.showFailureAlert(title: "Failure", message: "")
          completion(nil)
        }
      }
    })
    task.resume()
  }
}

Просмотр контроллера

class LoginViewController: UIViewController, UITextFieldDelegate {
  @IBOutlet var loginButton: UIButton!
  @IBOutlet var usernameOrEmailTextField: UITextField ?
  @IBOutlet var passwordTextField : UITextField ?
  var serviceBalance = 0.0
  let defaults = UserDefaults.standard
  var Reach : Reachability ? = Reachability()
  var viewModel : LoginViewModel ?

  override func viewDidLoad() {
    super.viewDidLoad()
    usernameOrEmailTextField?.delegate = self
    passwordTextField?.delegate = self
  }

  func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    usernameOrEmailTextField?.resignFirstResponder()
    passwordTextField?.resignFirstResponder()
    return (true)
  }

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

  @IBAction func loginButton(_ sender: Any) {
    viewModel?.setLoginObject(withUsername: usernameOrEmailTextField?.text, withPassword : passwordTextField?.text)
  }

  @IBAction func forgotPasswordButton(_ sender: Any) {
    self.performSegue(withIdentifier: "forgotPasswordSegue", sender: nil)
  }

  @IBAction func registerButton(_ sender: Any) {
    self.performSegue(withIdentifier: "registerUserSegue", sender: nil)
  }
}

ViewModel

class LoginViewModel: NSObject {

    var Reach: Reachability? = Reachability()
    var login: Login?
    var homeViewDictionary: [NSDictionary]?
    var APIClient: LoginServiceCall!
    var request = URLRequest(url: URL(string: "http://myapiuser/login")!)

    func setLoginObject(withUsername username: String?, withPassword password: String?){
        login?.username = username
        login?.password = password
        login?.appVersion = self.getAppVersion()
        login?.deviceID = self.getDeviceID()
        login?.deviceOS = self.getDeviceOs()

        APIClient.requestLogin(request: request, requestObject: login! { (AppDictionary) in
            DispatchQueue.main.async {
                self.homeViewDictionary = AppDictionary
            }
        }, completion: ())
    }

    func getAppVersion() -> String { return "0.2" }

    func getDeviceID() -> String {
        if let deviceid = UIDevice.current.identifierForVendor?.uuidString { return deviceid }
    }

    func getDeviceOs() -> String {
        let systemVersion = UIDevice.current.systemVersion
        let model = UIDevice.current.model
        return systemVersion+" "+model
    }

}
...