ЗАМЕТКИ

Model-view-controller (MVC)

Шаблон model-view-controller (MVC) состоит из трех связанных между собой объектов различного типа:

  • Model структура данных приложения (подклассы UIView)
  • View представление приложения, визуальные элементы управления (подклассы UIView)
  • View Controller контроллер для координации работы между моделью и представлением (подкласс UIViewController)

Шаблон MVC используется в UIKit.

Модель взаимодействует с контроллером посредством наблюдения за его свойствами, представление взаимодействует с контроллером через IBActions. У контроллера может быть множество связанных с ним моделей и представлений. Модели и представления могут быть переиспользованны другими контроллерами, переиспользование контроллера допустимо, но крайне нежелательно из его индивидуальной специфики и назначения.

Когда использовать?

Используйте этот шаблон в качестве отправной точки при создании приложений. MVC — это структурный шаблон, поскольку он предназначен для создания объектов в виде моделей, представлений или контроллеров.

Создание простой структуры Address:

import UIKit

public struct Address {
	public var street: String
	public var city: String
	public var state: String
	public var zipCode: String
}

import UIKit требуется для создания подкласса AddressView класса UIView:

public final class AddressView: UIView {
	@IBOutlet public var streetTextFeld: UITextField!
	@IBOutlet public var cityTextField: UITextField!
	@IBOutlet public var stateTextField: UITextField!
	@IBOutlet public var zipCodeTextField: UITextField!
}

Создание контроллера AddressViewController:

public final class AddressViewController: UIViewController {
	public var address: Address?
	public var addressView: AddressView! {
		guard isViewLoaded else {
			return nil
		}
		return (view as! AddressView)
	}
}

Контроллер содержит строгую ссылку на представление и модель. Переменная addressView проверяет условие isViewLoaded (загрузка представления) и, если оно оценивается как ложное, выполняет оператор else, обычно завершающий работу метода. Если значение true представление преобразуется в AddressView. Преимущество оператора guard заключается в более быстром исполнении: блок guard выполняется только в том случае, если условие ложно, и выход из блока осуществляется через оператор передачи управления, такой как return, break, continue или thrown. Это обеспечивает ранний выход и меньшее количество скобок.

Контроллер должен обновить addressView используя значение из переменной address.

Добавляем перегрузку функции viewDidLoad() и функцию для обновления адресных данных updateViewFromAddress() в контроллер. Также заменим свойство переменной address чтобы модель могла сообщать контроллеру об изменениях, который в свою очередь обновит представление.

public final class AddressViewController: UIViewController {
	public var address: Address? {
		didSet {
			updateViewFromAddress()
		}
	}
	public var addressView: AddressView! {
		guard isViewLoaded else {
			return nil
		}
		return (view as! AddressView)
	}
	
	public override func viewDidLoad() {
		super.viewDidLoad()
		updateViewFromAddress()
	}

	private func updateViewFromAddress() {
		guard let addressView = addressView,
			  let address = address else { return }
		addressView.stateTextField.text = address.street
		addressView.cityTextField.text = address.city
		addressView.stateTextField.text = address.state
		addressView.zipCodeTextField.text = address.zipCode
	}
}

Для обновления адреса из представления в контроллере используется метод IBAction:

@IBAction public func updateAddressFromView(_sender: AnyObject) {
		guard let street = addressView.streetTextFeld.text,
			  street.count > 0,
			  let city = addressView.cityTextField.text,
			  city.count > 0,
			  let state = addressView.stateTextField.text,
			  state.count > 0,
			  let zipCode = addressView.zipCodeTextField.text,
			  zipCode.count > 0 else {
				  return
			  }
		address = Address(street: street, city: city, state: state, zipCode: zipCode)
	}

MVC — хорошая отправная точка, но у нее есть ограничения. Не каждый объект точно впишется в категорию модели, представления или контроллера. Следовательно, приложения, использующие только MVC, как правило, содержат много логики в контроллерах.

В новой технологии SwiftUI используется модель MVVM (Model-View-ViewModel), вместе с этим использование классических MVC также допустимо.