objc-retain.com

Архитектура мобильного приложения: от iOS-проекта к бизнес-продукту

Мобильные решения
Архитектура мобильного приложения: от iOS-проекта к бизнес-продукту

Мобильное приложение перестало быть просто «экраном в кармане». Для бизнеса это точка продаж, операционный инструмент, канал поддержки и источник данных в одном устройстве. Если архитектура спроектирована правильно, продукт выдерживает рост пользователей, сложные интеграции и изменения в логике без бесконечных переделок. Если нет — команда быстро упирается в технический долг, медленные релизы и дорогую поддержку.

В мобильной разработке для бизнеса и особенно для недвижимости это видно особенно хорошо. Когда мы делали первые приложения для риэлторов на Objective-C, типичная ошибка была именно в том, что всё смешивалось в одном контроллере: и запрос к API каталога объектов, и форматирование цены, и логика избранного. Приложение должно не только красиво показывать каталог, но и работать с CRM, статусами сделок, офлайн-доступом, уведомлениями, ролями пользователей и аналитикой. Ниже — практический разбор, как выстроить архитектуру мобильного приложения так, чтобы оно стало полноценным бизнес-продуктом, а не набором экранов.

Что такое архитектура мобильного приложения на практике

Архитектура — это не «какой паттерн выбрать» и не «SwiftUI или UIKit». Это способ разложить продукт на части так, чтобы:

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

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

Из каких слоев обычно состоит приложение

Условно любое серьезное приложение можно разложить на несколько уровней. Это не догма, а скорее каркас, который помогает не смешивать ответственность:

Слой Задача Что туда относится
UI Показ данных и взаимодействие с пользователем экраны, кнопки, формы, навигация
Presentation Подготовка данных для интерфейса view model, presenter, state management
Domain Бизнес-правила сценарии, use case, валидация, правила работы с заказами и объектами
Data Получение и сохранение данных API-клиенты, база, кэш, репозитории
Infrastructure Внешние сервисы и технические детали push, аналитика, авторизация, файловая система

Такое разделение особенно полезно, когда продукт развивается не как стартап-демка, а как система с понятными процессами, ролями и интеграциями. Например, в приложении для управляющей компании слой Domain будет содержать правила валидации показаний счётчиков и маршрутизацию заявок, а UI — только отображать результат. Если завтра поменяется регламент обработки обращений, интерфейс даже не заметит.

Почему архитектура важнее, чем кажется на старте

На старте проекта часто хочется «сделать быстро». Это нормально, если MVP небольшой. Но у бизнес-приложения почти всегда есть скрытая траектория роста: сначала каталог и авторизация, потом фильтры, избранное, чаты, статусы сделок, роли, офлайн-режим, уведомления, отчетность, интеграция с CRM. Я проходил этот путь с девелоперскими приложениями: начинаешь с витрины ЖК, а через полгода заказчик просит добавить бронирование, электронную подпись документов и интеграцию с 1С. Если фундамент не заложен, каждая такая фича превращается в хирургическую операцию.

Если архитектура слабая, появляются типовые проблемы

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

Для мобильного продукта в недвижимости это критично: риэлтору нужен быстрый доступ к объектам и статусам, девелоперу — управляемый клиентский путь, а управляющей компании — стабильная работа с обращениями, уведомлениями и счетчиками. Когда риэлтор на показе пытается открыть карточку объекта, а приложение зависает на полминуты из-за того, что сетевой запрос и загрузка изображений блокируют главный поток — это не просто баг, а потерянная сделка.

Архитектура как основа бизнес-сценариев

В бизнес-приложении важен не экран сам по себе, а сценарий. Экран — это всего лишь проекция того, что происходит в доменной логике. Например:

  • пользователь ищет объект;
  • сравнивает несколько вариантов;
  • сохраняет в избранное;
  • бронирует показ;
  • передает заявку менеджеру;
  • получает статус и уведомления.

Каждый такой сценарий должен быть собран из понятных частей. Тогда приложение становится не просто каталогом, а рабочим инструментом. Я предпочитаю думать о сценариях как о цепочке use case’ов: «Забронировать показ» — это не метод в контроллере, а отдельный объект, который проверяет доступность слота, резервирует его через API и возвращает результат, готовый для отображения.

Примеры из недвижимости

  • Приложение для риэлтора: база объектов, карточки клиентов, статусы сделок, задачи, звонки, офлайн-доступ. Здесь критична синхронизация: риэлтор может обновить статус сделки в поле, а менеджер в офисе должен увидеть это мгновенно.
  • Приложение девелопера: витрина ЖК, бронирование, документы, прогресс стройки, сообщения, сервисные запросы. Часто добавляются виртуальные шоу-румы и 3D-туры — это дополнительная нагрузка на рендеринг и кэширование.
  • Приложение УК: обращения жильцов, показания счетчиков, заявки на ремонт, платежи, уведомления. Здесь на первый план выходят IoT-датчики и интеграция с системами здания.

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

Базовые архитектурные подходы: что выбирать и зачем

За годы работы с iOS-проектами я перепробовал разные паттерны — от классического MVC в Objective-C до Clean Architecture с координаторами на Swift. Каждый подход имеет свою цену и область применения. Важно не следовать моде, а понимать, какую проблему решает конкретный паттерн в вашем контексте.

MVC

Классический стартовый вариант. В Objective-C-проектах это была практически единственная рекомендация Apple, и многие начинали именно с него. Подходит для простых приложений и быстрых прототипов, но в крупных проектах быстро превращается в «свалку» логики. Контроллер на 2000 строк с сетевыми запросами, форматированием дат и валидацией форм — классика, которую я не раз разгребал.

Плюсы:

  • легко понять;
  • быстро начать.

Минусы:

  • контроллеры разрастаются;
  • сложно поддерживать;
  • бизнес-логика прилипает к UI.

MVP

Хорош для более строгого разделения логики и интерфейса. Часто удобен в проектах, где важна тестируемость и предсказуемость. Я применял его в проектах с наследием Objective-C, где нужно было постепенно вытаскивать логику из контроллеров, не переписывая всё сразу. Presenter становится прослойкой, которую можно покрыть unit-тестами без запуска UI.

Плюсы:

  • лучше отделяет UI от логики;
  • проще тестировать.

Минусы:

  • может быть многословным;
  • не всегда удобен для современных декларативных интерфейсов.

MVVM

Один из самых популярных вариантов для iOS-продуктов. Удобен там, где нужно строить экран вокруг состояния, а не вокруг ручного управления UI. С приходом SwiftUI и Combine этот паттерн стал практически стандартом индустрии. View Model хранит состояние экрана, а View просто реагирует на его изменения — никаких ручных вызовов reloadData.

Плюсы:

  • хорошо масштабируется;
  • удобен для реактивного обновления интерфейса;
  • проще разделять обязанности.

Минусы:

  • при плохой дисциплине view model тоже разрастается;
  • требует аккуратной работы со state.

Clean Architecture

Это не «еще один паттерн», а способ выстроить систему слоями: UI отдельно, бизнес-логика отдельно, источники данных отдельно. Особенно полезна в сложных проектах с долгим жизненным циклом. Когда мы мигрировали одно девелоперское приложение с монолита на Clean Architecture, самым болезненным было отделить доменные модели от DTO — серверные структуры просочились во все экраны, и замена API превратилась бы в катастрофу.

Плюсы:

  • удобно поддерживать большой код;
  • легче заменять API, базу, аналитику, SDK;
  • проще тестировать доменную логику.

Минусы:

  • дороже входной порог;
  • не стоит применять без необходимости к совсем маленькому приложению.

Как выбрать архитектуру под продукт, а не по моде

Выбор зависит не от тренда, а от контекста. Я видел стартапы, которые начинали с Clean Architecture и тонули в количестве протоколов и фабрик, не успев выпустить MVP. И видел проекты, которые выросли из «простого MVC» в неподдерживаемого монстра, потому что вовремя не ввели разделение слоев.

Короткая памятка

  • Небольшой MVP на 2–3 месяца — можно взять более простой подход. MVC или MVP сойдут, если держать контроллеры в рамках приличия.
  • Продукт с частыми изменениями и несколькими командами — лучше сразу закладывать разделение слоев. MVVM как минимум.
  • Приложение с интеграциями, ролями, офлайн-данными и длинным жизненным циклом — архитектура должна быть строгой. Clean Architecture или её облегчённая версия.
  • Если в продукте есть сложные сценарии сделки, уведомления, кэш и локальное хранилище — без четкого слоя domain и data быстро станет тесно.

Практический критерий

Если на вопрос «куда положить новую бизнес-логику?» команда отвечает «в экран», архитектура уже слабая.
Если ответ звучит как «в use case, репозиторий или сервис домена», фундамент у проекта нормальный. Это простой тест, который я провожу на код-ревью: спросите разработчика, где живёт правило расчёта скидки или валидации бронирования. Ответ многое скажет о состоянии проекта.

Что обязательно заложить в архитектуру бизнес-приложения

Есть несколько компонентов, без которых бизнес-приложение либо не взлетит, либо будет стоить слишком дорого в поддержке. Я выделяю шесть ключевых.

1. Управление состоянием

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

Нужно заранее определить:

  • где хранится состояние экрана;
  • кто им управляет;
  • как обрабатываются ошибки;
  • как работает обновление данных.

2. Работа с сетью и API

Большинство бизнес-приложений завязано на сервер. Значит, нужны:

  • единый слой API — чтобы не было разбросанных URLSession.dataTask по контроллерам;
  • обработка ошибок и таймаутов — пользователь должен видеть понятное сообщение, а не «код -1009»;
  • ретраи там, где они уместны — повторный запрос при таймауте, но не при 404;
  • нормальная работа с токенами — автоматический рефреш без разлогина;
  • понятный контракт с backend-командой — DTO должны быть задокументированы, а не угадываться.

3. Локальное хранение

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

  • кэш — какие данные живут долго, какие инвалидируются при каждом запуске;
  • локальную базу — Core Data, Realm или просто SQLite;
  • синхронизацию — что делать, если объект изменился и на сервере, и локально;
  • разрешение конфликтов — стратегия «последний выигрывает» или ручное слияние;
  • срок жизни данных — чтобы кэш не показывал проданную квартиру как доступную.

4. Навигация

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

5. Аналитика

Без событийной аналитики бизнес-продукт слепой. Нельзя улучшать воронку, если не знаешь, на каком шаге отваливаются пользователи. Нужно отслеживать:

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

6. Безопасность

Особенно важно для недвижимости и смежных сегментов:

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

Как выглядит хорошая архитектура глазами команды

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

Признаки здорового проекта

  • новые экраны добавляются без переписывания старых;
  • тестирование не требует ручного «кликанья» всего приложения;
  • API можно заменить без массовых правок UI;
  • ошибки локализуются быстро;
  • разработчики понимают, где искать нужную логику;
  • продукт легче передавать новому члену команды.

Признаки проблем

  • любой баг лечится «быстрым костылем»;
  • контроллеры или view model растут до тысячи строк;
  • бизнес-правила дублируются;
  • на каждый релиз страшно смотреть;
  • изменения в одном сценарии ломают смежные.

Пошагово: как спроектировать архитектуру мобильного приложения

За годы работы я выработал последовательность, которая помогает не упустить критичные вещи на старте. Порядок шагов важен: нельзя проектировать state management, не понимая бизнес-сценариев.

Шаг 1. Зафиксировать бизнес-сценарии

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

Шаг 2. Выделить доменные сущности

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

Шаг 3. Разделить данные и правила

Не смешивать формат ответа API и объект, с которым работает интерфейс. Серверный DTO не должен жить в UI напрямую. Я обычно ввожу мапперы на границе Data-слоя: DTO приходит, маппится в доменную модель, и только она идёт выше.

Шаг 4. Спроектировать state management

Нужно определить, как экран хранит состояние загрузки, ошибки, успеха, пустого результата и изменений от пользователя. Для этого хорошо подходят enum’ы с ассоциированными значениями: loading, loaded(data), empty, error(message). Экран просто свитчится по состояниям.

Шаг 5. Продумать offline-first или online-first

Если менеджеры и риэлторы работают вне офиса, офлайн становится не бонусом, а обязательным сценарием. Offline-first означает, что локальная база — основной источник данных, а сервер — средство синхронизации. Это сложнее в реализации, но критично для полевых сценариев.

Шаг 6. Настроить наблюдаемость

Логи, метрики, аналитика, crash reporting, трассировка запросов — всё это нужно заложить заранее. Без этого вы не узнаете, что у риэлторов в регионе падает 20% запросов из-за таймаута, пока они не начнут жаловаться в поддержку.

Типичные ошибки при проектировании

Ошибка Чем опасна Как избежать
Логика в UI код трудно тестировать и поддерживать выносить правила в domain layer
Прямые обращения к API из экрана хаос в сетевом слое использовать репозитории и сервисы
Нет единого state management баги и расхождение данных выбрать один способ управления состоянием
Сильная связность модулей сложно развивать продукт вводить границы между слоями
Игнорирование офлайна потери в полевых сценариях продумать кэш и синхронизацию
Нет аналитики невозможно улучшать воронку собирать события с первых релизов

Мини-чек-лист перед стартом разработки

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

Архитектура и iOS-проект: что важно именно на Apple-стеке

В iOS-проектах особенно важно не допускать, чтобы UIKit или SwiftUI «съели» всю логику. Интерфейс должен оставаться тонким слоем. Даже если проект исторически вырос из Objective-C, миграция в современную архитектуру возможна без полного переписывания — если двигаться поэтапно. Я проходил этот путь: вычленял доменную логику из старых контроллеров, оборачивал её в use case’ы, а UI постепенно переводил на новые компоненты.

На что обращать внимание

  • границы между legacy-кодом и новым модулем — чёткие протоколы взаимодействия;
  • управление памятью и жизненным циклом объектов — особенно если проект ещё частично на Objective-C с ручным retain/release;
  • изоляция сетевого слоя — чтобы замена Alamofire на URLSession не затронула бизнес-логику;
  • единый формат ошибок — доменные ошибки, а не NSError с разрозненными кодами;
  • совместимость старых экранов с новыми компонентами — координаторы или роутеры помогают;
  • постепенная декомпозиция монолита — не пытаться переписать всё сразу.

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

Как связать архитектуру с бизнес-целями

Архитектура нужна не ради красоты кода. Она должна помогать бизнесу в конкретных метриках:

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

Если приложение для недвижимости помогает быстрее бронировать объект, вести сделку и возвращать пользователя в сервис, значит архитектура работает на результат. Я измеряю это просто: сколько дней проходит от постановки задачи «добавить ипотечный калькулятор» до релиза. Если неделя, а не месяц — архитектура в порядке.

Вывод

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

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

FAQ

Какая архитектура лучше всего подходит для мобильного бизнес-приложения?

Для сложных продуктов чаще всего подходят MVVM или Clean Architecture, потому что они лучше разделяют логику, интерфейс и данные. MVVM даёт хороший баланс между строгостью и скоростью разработки, Clean Architecture — максимальную гибкость ценой большего количества кода.

Можно ли начать с простой архитектуры и потом усложнить?

Да, но только если с самого начала заложены понятные границы между слоями. Если бизнес-логика уже расползлась по контроллерам, выделить её потом будет стоить дорого. Лучше сразу отделить хотя бы доменные модели от DTO и не писать сетевые вызовы в UI.

Нужен ли офлайн-режим для приложения в недвижимости?

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

Почему нельзя держать бизнес-логику прямо в экране?

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

Когда архитектуру стоит пересматривать?

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