Используя подход MVC для разработки приложений для iOS, я хотел бы наблюдать за изменениями в модели, публикуя сообщения в NotificationCenter
.Для моего примера модель Person.swift
:
class Person {
static let nameDidChange = Notification.Name("nameDidChange")
var name: String {
didSet {
NotificationCenter.default.post(name: Person.nameDidChange, object: self)
}
}
var age: Int
var gender: String
init(name: String, age: Int, gender: String) {
self.name = name
self.age = age
self.gender = gender
}
}
Контроллер представления, который наблюдает за моделью, показан ниже:
class ViewController: UIViewController {
let person = Person(name: "Homer", age: 44, gender: "male")
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var ageLabel: UILabel!
@IBOutlet weak var genderLabel: UILabel!
@IBOutlet weak var nameField: UITextField!
@IBOutlet weak var ageField: UITextField!
@IBOutlet weak var genderField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
nameLabel.text = person.name
ageLabel.text = String(person.age)
genderLabel.text = person.gender
NotificationCenter.default.addObserver(self,
selector: #selector(self.updateLabels),
name: Person.nameDidChange, object: nil)
}
@IBAction func updatePerson(_ sender: Any) {
guard let name = nameField.text, let age = ageField.text, let gender = genderField.text else { return }
guard let ageNumber = Int(age) else { return }
person.name = name
person.age = ageNumber
person.gender = gender
}
@objc func updateLabels() {
nameLabel.text = person.name
ageLabel.text = String(person.age)
genderLabel.text = person.gender
}
}
Пример приложения работает следующим образом:
- Введите имя, возраст и пол в текстовых полях
- Нажмите кнопку
updatePerson
, чтобы обновить модель из значений текстового поля - При обновлении моделиобозреватель уведомлений вызывает функцию
updateLabels
для обновления пользовательского интерфейса.
Этот подход требует, чтобы person.name
устанавливался последним, в противном случае необходимо дважды нажать кнопку updatePerson
, чтобы обновить всепользовательский интерфейс.И поскольку я наблюдаю только одно свойство, уведомление не представляет весь класс.Есть ли лучший способ наблюдать за изменениями моделей (классов или структур) в Swift?
Примечание. Меня не интересует использование RxSwift для этого примера.