Гибкая модульная архитектура VIPER для iOS с генераторами кода

Приложение растёт, и привычная схема слоёв начинает тормозить сборку и выпуск обновлений. Мы проектируем и внедряем модульную архитектуру VIPER для iOS под ключ: разбиваем проект на независимые модули, снимаем связность и ускоряем сборку кратно. Команда получает каркас, который выдерживает рост продукта и смену разработчиков.

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1734 услуг
Гибкая модульная архитектура VIPER для iOS с генераторами кода
Сложный
~3-5 дней
Часто задаваемые вопросы

Что даёт модульный каркас: скорость сборки и предсказуемость

Модульный каркас на схеме VIPER разбивает приложение на независимые модули, где экран — это набор изолированных слоёв: представление, логика, работа с данными. Слои связаны только через контракты, поэтому правка в одном экране не задевает соседние, а сборка пересобирает один модуль вместо всего проекта — время сборки проекта перестаёт расти вместе с числом экранов.

Однотипные слои не пишем руками: генератор модулей по шаблону создаёт заготовки с едиными точками входа и уже связанными зависимостями, разработчик сразу пишет логику. Структура остаётся одинаковой во всех разделах — новый инженер читает незнакомый экран по тем же правилам, что и свой. Каркас держим в рамках конвенций Apple для актуальной ветки платформы.

Переиспользование экранов здесь работает не как копирование кода: типовые сценарии — авторизация, список, карточка, фильтры — вынесены в самостоятельные модули и подключаются к новому разделу без правок внутри. Объём нового кода на экран падает в разы, а поведение типовых блоков не расходится между разделами.

Изолированные слои дают предсказуемые проверки: логику тестируем отдельно от интерфейса и без запуска всего приложения. Доля путей, закрытых проверками, растёт, а дефекты на стыках модулей — самая дорогая категория по стоимости исправления — перестают доходить до релиза.

Режимы организации слоёв VIPER: сравнение подходов

Слои VIPER можно собрать по-разному, и разница видна не на первом экране, а на двадцатом — когда правка одного сценария тянет за собой View, Router и весь набор тестов. Ключевой вопрос: где проходят границы модулей и кто владеет контрактами — протоколами Presenter-а, Interactor-а и Router-а.

Вариант Когда подходит Ограничения
Ручные контракты внутри одного модуля 2–5 экранов, короткий срок Ручное копирование, слои расходятся, тесты дублируются
Генерация по шаблонам Десятки однотипных экранов Шаблон диктует структуру, генератор надо обновлять на живом проекте
Отдельно собираемые модули Несколько команд, переиспользование Дороже старт, строгие правила версий контракта
Общий слой контрактов и модулей Крупный продукт с потоками Без дисциплины общий слой разрастается

Выбор идёт по двум осям: число экранов и число команд. Пока экранов немного, генерация по шаблонам убирает ручное копирование и фиксирует контракт в одном месте, но общий слой пока не нужен. Когда появляются независимые потоки и переиспользование, выносим модули за границу сборки и версионируем контракты.

Переход делается поэтапно, без переписывания: сначала вводим шаблон, затем выносим готовый модуль — слои остаются на месте, меняется только адрес контракта. Такой путь позволяет сравнить варианты на своём коде, а не на презентации.

Этапы перевода приложения на модульную схему

Перевод работающего приложения на модульную схему — не разовый рефакторинг, а последовательность шагов, где каждый заканчивается проверяемым результатом. Внедрение модульной схемы ведём волнами: сначала фиксируем текущее состояние, затем меняем один участок и убеждаемся, что поведение не поехало. Разработка при этом не останавливается — релизы продолжают выходить.

Порядок работ выглядит так.

  1. Аудит зависимостей. Собираем карту связей: где логика размещена в слое представления, какие классы тянут за собой половину проекта, где циклы и скрытые обращения к общему состоянию. На выходе — перечень узлов и очередность их распила.
  2. Схема модулей и план перевода. Определяем границы: что становится самостоятельным модулем, что уходит в общий слой, какие интерфейсы публичные. План перевода разбит на волны — по одному-два модуля за релиз, чтобы изменения оставались обозримыми.
  3. Настройка генераторов кода. Заводим шаблоны модуля — представление, интерактор, презентер, сущность, маршрутизатор — с едиными именами и структурой папок. Новый модуль создаётся командой, а не копированием соседнего, поэтому разнобой между участками не накапливается.
  4. Пилотный модуль. Один независимый участок переводим целиком по новой схеме и встраиваем в приложение без изменения поведения. Пилот показывает реальную стоимость шага и то, сколько времени экономят генераторы.
  5. Регрессионная проверка. Прогоняем автотесты на интеракторы и презентеры, проходим вручную критичные сценарии и сравниваем поведение до и после. Отдельно фиксируем время сборки и размер артефактов — по ним видно, что модульность работает, а не только описана.
  6. Передача документации и обучение команды. Отдаём схемы модулей, правила границ, чек-листы проверки кода и инструкцию по генераторам. Разбираем всё на живом коде, чтобы команда дальше переводила модули своими силами.

Что остаётся у команды после передачи проекта

Передача проекта — это не архив с исходным кодом, а набор артефактов, по которым команда заказчика продолжает работу без авторов. Всё перечисленное лежит в репозитории рядом с кодом и в регламентах: инженер читает их и берёт задачу в работу самостоятельно.

  • Документация по модулям — назначение, входы и выходы, связи со слоями VIPER-модуля; видно, что можно менять изолированно, не задевая остальное приложение.
  • Шаблоны и настройки генерации — заготовки модулей и конфигурация инструментов, создающих новый код по принятому стандарту; шаблон правится в одном месте, и следующие модули рождаются согласованными.
  • Карта зависимостей — схема связей модулей, чтобы новый функционал не превращал архитектуру в клубок.
  • Правила ревью кода — чек-лист проверяющего: границы слоёв, обработка ошибок, покрытие проверками, договорённости по именованию.
  • Порядок выпуска версий — путь от ветки до публикации в магазинах приложений: кто подтверждает, как готовится описание изменений, как откатывается неудачный релиз.
  • Инструкции для новых инженеров — окружение, точки входа, типовые задачи первой недели; выход на самостоятельные правки занимает дни, а не месяцы.

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

Кейс: сократили время сборки и убрали класс отказов

Кейс мобильного приложения на Swift: к началу работ оно собиралось единой сборкой, где любой экран тянул за собой весь код. Правка в одном месте запускала пересборку всего проекта, и цикл проверки занимал минуты, которых у команды не было. Дороже обходились не сами задержки, а ошибки: большинство отказов всплывало не внутри экранов, а на стыках между слоями, где один слой дёргал другой напрямую.

Перевод на модули

Мы разложили приложение на слои по схеме VIPER — экран, взаимодействие, сущность, представление, маршрутизация — и зафиксировали контракты между ними. Генераторы кода создают каркас нового модуля и заготовки тестов, поэтому разработчик сразу пишет логику, а не воспроизводит однотипные файлы. Сборка стала инкрементальной: изменение в одном модуле не тянет за собой остальные.

Цифры до и после

Полная сборка сократилась втрое, сборка после типовой правки — с десятков секунд до единиц. Доля отказов на стыках модулей упала с 30% до 6%: контракты проверяются на этапе сборки, а не на тестировании и не на релизе. Трудозатраты на доработку нового экрана — 2 дня вместо 1,5 недель, потому что структура, навигация и тесты уже сгенерированы. Откат отдельного модуля теперь тоже не требует пересборки всего приложения.

Что делать, если монолит уже развёрнут и переписывать нельзя

Переписывать монолит целиком не нужно и почти всегда вредно. Вопрос не в том, можно ли ввести модульные слои, а в том, как делать это частями: новый код для iOS собирается по архитектуре VIPER, а старое ядро продолжает работать рядом и постепенно теряет вес.

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

Выпуск версий при этом не останавливается. Один релиз добавляет один-два модуля и переводит одну-две унаследованные области, сборка и автотесты покрывают оба слоя одновременно, а откат возможен на уровне отдельной области, а не всего приложения. Уже первые поставки снижают долю правок, задевающих несвязанные части кода.

Постепенное внедрение модулей выигрывает у полного переписывания по рискам. При переписывании паритет с текущим поведением приходится восстанавливать по косвенным признакам, сроки растут, а старый код всё это время продолжает меняться и расходиться с новой веткой — выпуск откладывается до момента, когда готово сразу всё.

Поэтому поэтапная переработка планируется релизами: доля кода под модулями растёт, доля изменений в монолите падает, а объём первого этапа считается по числу областей с самой высокой частотой правок.

Технические сомнения: тесты, зависимости, найм под схему

Возражения к жёсткой слоистой схеме повторяются из проекта в проект: не усложнит ли она поддержку старого кода, не потребует ли отдельного инженера и сколько времени уйдёт на обучение команды. Отвечаем по существу.

Как тестировать слои по отдельности?

Презентер проверяется без интерфейса, интерактор — без сетевых вызовов: зависимости подменяются заглушками на границах протоколов. Логика сценариев покрывается быстрыми проверками, а тяжёлые сквозные прогоны остаются для сборки экрана целиком — набор тестов перестаёт расти вместе с проектом.

Что делать с зависимостями между модулями?

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

Нужен ли отдельный инженер под поддержку?

Как правило, нет. Правка локализуется в одном слое, поэтому задача достаётся тому, кто свободен, а не тому, кто «писал этот экран». Трудоёмкость поддержки падает ещё и потому, что не нужно держать в голове связи по всей кодовой базе. Старый код переводится на схему постепенно, по мере правок, без остановки релизов.

Как быстро новый разработчик входит в проект?

Первая правка в рабочей версии — в пределах первой недели: у каждого слоя одна зона ответственности, а генераторы кода собирают новый модуль по готовому шаблону. Правила и примеры зафиксированы в коротком внутреннем руководстве, поэтому обучение не держится на одном человеке.

Обсудим задачу и вернёмся с планом работ

Чтобы разговор был предметным, а не общим, к обращению полезно приложить то, что у вас уже есть. Готовить презентации не нужно — достаточно рабочего контекста, по которому видно реальный объём работ.

  • описание продукта и ключевых пользовательских сценариев — хватит двух-трёх абзацев;
  • текущее состояние кода: есть ли проект, на какой стадии, что мешает развивать его дальше;
  • перечень экранов и переходов между ними — из него вырастает схема модулей под проект;
  • требования к интеграциям: авторизация, платежи, аналитика, уведомления, офлайн-режим;
  • ограничения по срокам и платформам, доступы к существующим репозиториям и учётным записям;
  • как сейчас проходит выпуск: сборка, проверки, публикация в магазинах приложений.

После обращения мы разбираем ситуацию и возвращаемся с оценкой и планом работ. В плане — внедрение модульной схемы: каждый модуль закрывает один сценарий и не тянет за собой соседние, генераторы кода снимают рутину с типовых экранов, а поддержка мобильного приложения идёт по понятному регламенту выпуска.

Опишите задачу в удобном виде — вернёмся с оценкой и планом работ. Если кода ещё нет, это не помеха: схему модулей под проект соберём с нуля, под ваш продукт и вашу команду.

Наши компетенции:

Последние работы

  • Разработка мобильного приложения для компании FEEDME
    Разработка мобильного приложения для компании FEEDME
    1010
  • Разработка мобильного приложения для компании XOOMER
    Разработка мобильного приложения для компании XOOMER
    903
  • Разработка мобильного приложения для компании RHL
    Разработка мобильного приложения для компании RHL
    1332
  • Разработка мобильного приложения для компании ZIPPY
    Разработка мобильного приложения для компании ZIPPY
    1180
  • Разработка мобильного приложения для компании Affhome
    Разработка мобильного приложения для компании Affhome
    1107
  • Разработка мобильного приложения для компании FLAVORS
    Разработка мобильного приложения для компании FLAVORS
    714