Вся бизнес-логика должна быть внутри ViewModel. ViewModel должна вызывать любой метод внутри UserManager. UserManager должен вернуть результат, проанализированный как Модель, в ViewModel. Затем ViewModel необходимо отформатировать данные и предупредить ViewController о завершении события / данных / сети и т. Д.
Примеры форматирования данных:
- Допустим, сетевой запрос дает вам
firstName
и lastName
. Но у вас есть только 1 ярлык для отображения полной вещи. ViewModel должен добавить эти строки вместе (с пробелом) и предоставить свойство fullName
для VC.
- Если вы получили двойной, но вам нужно отформатировать его в валюте и отобразить символ.
- Получение метки времени и форматирование в строку даты.
Это то, что должен делать ViewModel. Так что они могут быть протестированы независимо от кода пользовательского интерфейса и жизненного цикла.
Сообщение:
Вы можете использовать стандартные разработки Apple API и создать протокол ViewModel
с делегатом и обратным вызовом. Каждая виртуальная машина подтверждает протокол, VC устанавливает себя в качестве делегата своей виртуальной машины и запускает ваш код в функции обратного вызова делегата VC.
Нейминг:
Слово «Менеджер» вышло из употребления, потому что обычно это слово используется по умолчанию, когда использование класса неясно. По этой причине у него тысяча разных определений. Класс, отвечающий за выполнение сетевых запросов и / или сохранение состояния, должен называться «Сервис». т.е. "UserService".
Состояние совместного использования:
Я, вероятно, собираюсь рассердить многих людей этим. Но когда необходимо разделить состояние между несколькими VC, компонентами, виртуальными машинами и т. Д., Я следую шаблонам проектирования / архитектуре, которые имеет Angular. Я делаю свои классы обслуживания одиночек. Пусть они хранят состояние. Затем каждая модель представления имеет один источник правды для каждого элемента и может форматировать его по своему желанию.
Другие люди используют такие среды, как RxSwift, и используют Observables и аналогичные технологии. Мое личное мнение таково, что это огромное излишество, включает в себя огромную кривую обучения, означает добавление большого количества больших библиотек и влечет за собой большой риск для проекта. Я предпочитаю придерживаться шаблонов, уже доступных и работающих в экосистеме, и упростить задачу.
Редактировать: один ко многим:
Это может зависеть от вашего варианта использования и архитектурных решений. Я обнаружил, что можно избежать проблемы «один ко многим» в большинстве моих случаев использования, так как синглтон сохраняет состояние и заставляет VC запускать что-то в ViewModel при каждом вызове viewDidAppear
. Каждый раз, когда открывался ВК, он получал последние данные и продолжал. Причина, по которой я стараюсь избегать «один-ко-многим», заключается в том, что в большинстве случаев на экране присутствует только 1 виртуальный канал, и в любой момент времени выполняется код (использование childViewControllers является исключением). Я обнаружил, что можно полностью обойти эту проблему и сделать приложения простыми, изменив способ взаимодействия с данными, а не изменив структуру API-интерфейсов Apple.
Теперь, в зависимости от вашего варианта использования, это может не сработать, если у вас несколько таймеров и много переключений экрана, может быть шанс пропустить событие.
NotificationCenter - не мой любимый подход, но если бы у меня была ситуация один ко многим, которую я не мог избежать, я бы попробовал. Как уже упоминалось в статье, есть некоторые недостатки быстрых функций, которые вы можете получить с помощью этого средства. Это, по крайней мере, имеет то преимущество, что это то, что было вокруг в течение долгого времени и хорошо понято и вряд ли сильно изменится. Там не будет большой кривой обучения, если другие разработчики работают над этим приложением.
Другой подход, упомянутый в статье, интересен, создавая собственную урезанную версию RxSwift для добавления наблюдателей в проект. В настоящий момент моя проблема с RxSwift заключается в том, что люди не используют его в сочетании с синглетонами или какой-то центральной точкой контроля. Когда у вас есть Observable на объекте A, Observed by B, у которого также есть другая Observable Observable от C, которая вызывает функцию на D, которая наблюдается E, F и G .... и так далее. Этот стиль кода невероятно запутан, труден для чтения, подвержен ошибкам и труден для отладки. До тех пор, пока этого избегают и его единый объект, который имеет наблюдаемую и все ViewModels, наблюдают, я думаю, что-то подобное будет хорошо, если вы захотите приложить усилия для его создания и обслуживания.