- Xcode 9.1
Для более комфортной разработки вы можете использовать
*Generatus: https://github.com/Ryasnoy/Generatus
View- делегирует события взаимодействия с пользователем вPresenterи отображает данные, переданныеPresenter- Все
UIViewController,UIView,UITableViewCell, сабклассы принадлежат слоюView - Обычно
Viewявляется пассивным - оно не должно содержать сложной логики, поэтому в большинстве случаев нам не нужно писать Unit Tests для него. Presenter- содержит логику представления и сообщаетView, что необходимо отобразить- Чаще всего нам необходим один
Presenterна одно представление (view controller) - Он не ссылается на конкретный тип
View, а скорее ссылается на протоколView, который обычно реализуется подклассомUIViewController - Он должен быть простым классом
Swiftи не ссылаться ни на какие классыiOSфреймворков - это упрощает повторное использование, возможно, в приложенииmacOS - Он должен покрываться Unit Tests
Configurator- вводит граф зависимостей для объекта представления (view controller)- Вы можете с легкостью использовать DI (dependency injection) библиотеки. К сожалению DI библиотеки еще недостаточно зрелы в
iOS/Swift - Обычно он содержит очень простую логику и нам не нужно писать для этого Unit Tests
Router- содержит логику навигации от одного представления (view controller) к другому- В некоторых гайдах можно встретить такое название как
FlowController - Очень сложно поддается написанию Unit Tests поскольку содержит много ссылок на классы
iOSфреймворков. Поэтому нужно стараться делаеть его максимально простым. - Обычно он ссылается только на
Presenter, но из-за методаfunc prepare (for segue: UIStoryboardSegue, sender: Any?)иногда ссылаемся на него и воViewController
UseCase / Interactor- содержит бизнес-логику для конкретного варианта использования в приложении- На него ссылается
Presenter.Presenterможет ссылаться на несколькоUseCasesпоскольку обычно используется несколько вариантов использования на одном экране - Он манипулирует
Entitiesи связывается сGatewaysдля извлечения / сохранения объектов - Протоколы
Gatewayдолжны быть определены в слояхApplication Logicи реализованы вGateways & Framework Logic - Разделение, описанное выше, гарантирует, что
Application Logicзависит от абстракций, а не от фактических фреймворков / реализаций - The separation described above ensures that the
Application Logicdepends on abstractions and not on actual frameworks / implementations - Он должен покрываться Unit Tests
Entity- простыеSwiftклассы / структуры- Модели объектов, используемых вашим приложением, такие как
Order,Product,Shopping Cartи тд
Gateway- содержит фактическую реализацию протоколов, определенных в слоеApplication Logic- Мы можем реализовать например, протокол
LocalPersistenceGatewayиспользуяCoreDataorRealm - Мы можем реализовать например, протокол
ApiGatewayиспользуяURLSessionorAlamofire - Мы можем реализовать например, протокол
UserSettingsиспользуяUserDefaults - Он должен покрываться Unit Tests
Persistence / API Entities- содержат представления, специфичные для структуры- Например, у нас может быть
CoreDataOrderкоторый является подклассомNSManagedObject CoreDataOrderне будет передан на слойApplication Logic, но слойGateways & Framework Logic"преобразует" его в сущностьOrderопределенный в слоеApplication LogicFramework specific APIs- содержит реализации специфичных дляiOSAPI, таких как датчики / bluetooth / camera
Демо проект находится по ссылке:
https://github.com/FortechRomania/ios-mvp-clean-architecture
- Демо-приложения пытаются выявить довольно сложный набор функций, который оправдывает использование представленных выше понятий
- Были написаны следующие Unit Tests:
BooksPresenterTest- демонстрирует, как вы можете протестировать логикуPresenterDeleteBookUseCaseTest- демонстрирует, как вы можете протестировать прикладную / бизнес-логику, а также как протестировать асинхронный код, который использует обработчики завершения иNotificationCenterCacheBooksGatewayTest- демонстрирует, как вы можете протестировать политику кэшированияCoreDataBooksGatewayTest- демонстрирует, как вы можете протестироватьCoreDataApiClientTest- демонстрирует, как вы можете протестировать слой API / Networking вашего приложения, заменив стекURLSession- Code comments можно найти в нескольких классах, выделяя различные дизайнерские решения или ссылаясь на последующие ресурсы
- Структура проекта пытается имитировать концепцию Screaming Architecture, которая может быть найдена в разделе ссылок
- Высокоуровневая диаграмма UML:

Предоставление большого количества мобильных приложений - это тонкий клиент поверх API и большинство из них содержат небольшую бизнес-логику (поскольку большинство бизнес-логик найдено в API), некоторые из концепций «чистой архитектуры» могут быть спорным в мобильном мире. Ниже вы можете найти:
- Создание представления для каждого уровня (API, CoreData) может показаться излишним. Если ваше приложение в значительной степени зависит от API, который находится под вашим контролем, тогда может возникнуть смысл моделировать как объект, так и представление API, используя тот же класс. Однако вы не должны допускать представление персистентности (например, подкласс
NSManagedObject) в других слояхParse - Если вы обнаружите, что в большинстве случаев ваши
UseCase / Interactorпросто делегируют действия вGateways, возможно, вам не нужно делатьUseCase / Interactor, вы можете использоватьGatewaysнепосредственно вPresenter - Если вы хотите еще больше усилить разделение слоев, вы можете рассмотреть возможность перемещения всех слоев в свои собственные модули
- Некоторые могут подумать о том, что создание методов
display (xyz: String)наCellViewявляется чрезмерным и что передача объектаCellViewModelвоCellViewи представление конфигурации с моделью просмотра является более простым. Если вы хотите, чтобыViewсохранялась как пассивный элемент, вы можете создать методы, но постарайтесь сохранить простую логику
Вышеуказанный список определенно не является полным, и если у вас есть спорные вопросы, пожалуйста, создайте issue, и мы можем обсудить ее и включить в список выше.
Имейте в виду, что вам не нужно принимать все проектные решения заранее и что вы можете реорганизовать их во время своей работы.
Обсудите все дизайнерские решения с членами вашей команды и убедитесь, что вы все согласны.
https://github.com/FortechRomania/ios-mvp-clean-architecture/blob/master/readme.md#useful-resources
Оригинал: - https://github.com/FortechRomania/ios-mvp-clean-architecture
Если вы нашли ошибку, создайте issue или PR с исправлением.
Oleg Ryasnoy Сообщество iOS Разработчиков в Telegram: https://t.me/devios