Sono uno sviluppatore iOS e sono colpevole di avere Massive View Controller nei miei progetti, quindi ho cercato un modo migliore per strutturare i miei progetti e ho trovato l'architettura MVVM (Model-View-ViewModel). Ho letto molto MVVM con iOS e ho un paio di domande. Spiegherò i miei problemi con un esempio.
Ho un controller di visualizzazione chiamato LoginViewController
.
LoginViewController.swift
import UIKit
class LoginViewController: UIViewController {
@IBOutlet private var usernameTextField: UITextField!
@IBOutlet private var passwordTextField: UITextField!
private let loginViewModel = LoginViewModel()
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func loginButtonPressed(sender: UIButton) {
loginViewModel.login()
}
}
Non ha una classe Model. Ma ho creato un modello di visualizzazione chiamato LoginViewModel
per inserire la logica di convalida e le chiamate di rete.
LoginViewModel.swift
import Foundation
class LoginViewModel {
var username: String?
var password: String?
init(username: String? = nil, password: String? = nil) {
self.username = username
self.password = password
}
func validate() {
if username == nil || password == nil {
// Show the user an alert with the error
}
}
func login() {
// Call the login() method in ApiHandler
let api = ApiHandler()
api.login(username!, password: password!, success: { (data) -> Void in
// Go to the next view controller
}) { (error) -> Void in
// Show the user an alert with the error
}
}
}
-
La mia prima domanda è semplicemente che la mia implementazione MVVM sia corretta? Ho questo dubbio perché ad esempio inserisco l'evento di tocco del pulsante di accesso (
loginButtonPressed
) nel controller. Non ho creato una vista separata per la schermata di accesso perché ha solo un paio di campi di testo e un pulsante. È accettabile che il controller abbia metodi evento legati agli elementi dell'interfaccia utente? -
La mia prossima domanda riguarda anche il pulsante di accesso. Quando l'utente tocca il pulsante, i valori del nome utente e della password devono essere passati a LoginViewModel per la convalida e, in caso di esito positivo, alla chiamata API. La mia domanda su come passare i valori al modello di vista. Dovrei aggiungere due parametri al metodo
login()
e passarli quando li chiamo dal controller di visualizzazione? O dovrei dichiarare le proprietà per loro nel modello di vista e impostare i loro valori dal controller di visualizzazione? Quale è accettabile in MVVM? -
Utilizza il metodo
validate()
nel modello di visualizzazione. L'utente dovrebbe essere avvisato se uno di questi è vuoto. Ciò significa che dopo il controllo, il risultato deve essere restituito al controller della vista per intraprendere le azioni necessarie (mostrare un avviso). Stessa cosa con il metodologin()
. Avvisa l'utente se la richiesta fallisce o passa al controller della vista successivo se ha successo. Come posso notificare il controller di questi eventi dal modello di visualizzazione? È possibile utilizzare meccanismi di binding come KVO in casi come questo? -
Quali sono gli altri meccanismi di associazione quando si utilizza MVVM per iOS? KVO è uno. Ma ho letto che non è adatto per i progetti più grandi perché richiede un sacco di codice boilerplate (registrando / annullando la registrazione degli osservatori, ecc.). Quali sono le altre opzioni? So che ReactiveCocoa è un framework usato per questo, ma sto cercando di vedere se ci sono altri nativi.
Tutti i materiali che ho trovato su MVVM su Internet hanno fornito poche informazioni su queste parti che sto cercando di chiarire, quindi apprezzerei molto le tue risposte.