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.