Начнём с реального кейса. Клиент из финтеха хотел запустить приложение для инвестиций за 3 месяца. Выбрали Flutter, чтобы сэкономить на команде. Через 4 месяца выяснилось, что интеграция с Apple Pay требует нативного кода, а Flutter плагин не поддерживает все фичи. Пришлось писать native bridge, что замедлило релиз на 2 недели. Правильный выбор стека на старте — не про моду, а про реальные технические ограничения.
За годы практики мы провели консультации для 30+ проектов: от простого каталога до сложных AR-приложений. Каждый раз используем системный подход: собираем требования, строим матрицу компромиссов и даём рекомендацию с обоснованием. В этой статье — как не ошибиться с выбором технологии.
Не важно, ищете ли вы ответ на вопрос 'Swift или Kotlin' или 'Flutter vs React Native' — важно понимать, какие задачи решает приложение. От этого зависит не только скорость разработки, но и стоимость поддержки в течение 1–2 лет.
Какой стек выбрать для MVP?
Для быстрого запуска с минимальным бюджетом React Native или Flutter позволяют запустить обе платформы одной командой. React Native ускоряет разработку в 1.5 раза по сравнению с нативной, но может терять 10–20% производительности на сложных анимациях. Flutter обеспечивает в 2 раза более быструю разработку относительно двух нативных команд, сохраняя стабильные 60fps без «мостового» overhead.
Если приложение критично к производительности или использует нативные API (ARKit, CoreNFC), выбираем нативную разработку — Swift или Kotlin. Это даёт максимальную производительность и доступ ко всем API, но требует двух команд.
Как выбрать технологический стек: пошаговая инструкция
-
Определите приоритетные платформы — iOS, Android или обе. Если только одна, кроссплатформа теряет смысл.
-
Оцените требуемые нативные API — ARKit, CoreNFC, HealthKit, Bluetooth LE. Для них нужна нативная разработка или продвинутые плагины.
- Оцените команду — какой у вас состав и экспертиза. Переучивать Swift-разработчика на Flutter — это 3–6 месяцев снижения velocity.
-
Сравните бюджет — две нативные команды против одной кроссплатформенной. С учётом поддержки разница может достигать 40%.
Сравнение подходов
| Подход |
Скорость разработки |
Производительность |
Нативный UX |
Команда |
| Swift (iOS native) |
Средняя |
Максимальная |
Да |
iOS-разработчики |
| Kotlin (Android native) |
Средняя |
Максимальная |
Да |
Android-разработчики |
| React Native |
Высокая |
Хорошая |
Частично |
JS/TS разработчики |
| Flutter |
Высокая |
Очень хорошая |
Свой Dart-рендерер |
Flutter-разработчики |
| Kotlin Multiplatform |
Средняя |
Высокая |
Да (нативный UI) |
Kotlin-разработчики |
React Native — хороший выбор когда: у команды есть React/TypeScript опыт, большая часть приложения — информационные экраны и формы, важна скорость MVP. Плохой выбор когда: нужны сложные анимации 60fps, тяжёлая работа с камерой/Bluetooth, или приложение — это игра. React Native ускоряет разработку в 1.5 раза по сравнению с нативной, но может терять 10–20% производительности на сложных анимациях.
Flutter — хороший выбор когда: нужны обе платформы с одинаковым дизайном, кастомный UI не совпадает с платформенным (нет смысла бороться за нативный look-and-feel), команда готова работать с Dart. Dart-рендерер на Skia/Impeller даёт стабильные 60fps без «мостового» overhead React Native. Flutter позволяет сэкономить до 40% бюджета на команду по сравнению с двумя нативными командами.
Kotlin Multiplatform — для команд с сильной Android/Kotlin экспертизой, которые хотят разделить бизнес-логику между iOS и Android, сохранив нативный UI на каждой платформе.
Нативная разработка — когда производительность критична (игры, AR, обработка видео в реальном времени), или когда приложение глубоко использует платформенные API: HealthKit, ARKit, CoreNFC, CarPlay на iOS; CameraX с ML Kit, Android Auto, WearOS на Android.
Сравнение затрат на команду и поддержку
| Подход |
Размер команды (iOS+Android) |
Относительная стоимость поддержки в год |
| Две нативные команды |
4–6 разработчиков |
1.5–2x от MVP |
| React Native / Flutter |
2–3 разработчика |
~1x от MVP |
| Kotlin Multiplatform |
3–4 разработчика |
~1.2x от MVP |
Почему нативная разработка не всегда лучше?
Нативная разработка даёт максимальную производительность и доступ к API, но требует две команды. Если приложение не использует сложные платформенные фичи, затраты на две команды не оправданы. Наш опыт показывает, что 70% проектов могут быть реализованы на Flutter или React Native без потери качества. По данным Apple App Store Review Guidelines, приложения должны использовать платформенные API для критических функций, что требует нативной разработки.
Что входит в консультацию по выбору стека
- Документ с обоснованием выбора стека
- Примерная roadmap разработки
- Оценка команды и необходимых ролей
- Анализ рисков и альтернатив
- Рекомендации по инфраструктуре (CI/CD, сторидж)
- Поддержка на этапе старта разработки
Как мы это делаем
Консультация включает: анализ требований → матрица компромиссов → рекомендация с обоснованием → оценка стоимости и сроков для каждого варианта. Не продаём «Flutter везде» — выбираем то, что решает конкретную задачу.
Формат работы: 2–4 часа интервью + 3–5 рабочих дней на подготовку детального документа. Стоимость рассчитывается индивидуально — свяжитесь с нами для консультации.
Какие вопросы мы задаём перед рекомендацией?
- Состав текущей команды? Переучивать Swift-разработчика на Flutter — это 3–6 месяцев снижения velocity.
- Функционал первого года? Если в roadmap есть AR-примерка, нативный Swift неизбежен.
- Нужна ли офлайн-работа? Room (Android) и Core Data / SwiftData (iOS) — зрелые решения; офлайн в React Native/Flutter — дополнительная сложность.
- Целевой рынок? Если только iOS — нет смысла тратить ресурсы на кроссплатформу.
- Бюджет на поддержку? Two separate native apps = две команды; Flutter/RN = одна.
Закажите анализ стека — получите твёрдую основу для старта разработки. Свяжитесь с нами — мы поможем выбрать стек под вашу задачу.
Архитектура мобильных приложений
Приложение собрано в одном ViewController на 2000 строк. Сетевые вызовы, бизнес-логика, обновление UI — всё в одном месте. Добавить новую фичу без регрессии сложно, написать тест невозможно. Это не «плохой код» — это отсутствие архитектуры. И это встречается чаще, чем можно ожидать, даже в production-приложениях с миллионом пользователей.
Мы проектируем архитектуру под ключ: от выбора паттерна до полной структуры проекта с тестами и документацией. За 7–10 дней получаете чистый модульный код, готовый к масштабированию.
Архитектурные паттерны в мобайле решают одну задачу: отделить UI от логики так, чтобы каждая часть была тестируемой и заменяемой.
MVVM: базовый паттерн
Model-View-ViewModel — стандарт для iOS (SwiftUI + Combine/async, UIKit + Combine) и Android (Jetpack ViewModel + StateFlow + Compose). ViewModel содержит состояние UI и бизнес-логику. View только отображает состояние и передаёт намерения пользователя в ViewModel. Model — данные и их источник.
Ключевое правило: ViewModel не знает об UIKit или Android View-классах. Нет импортов UIKit, нет Context-зависимостей (кроме Application context через Hilt). Это гарантирует тестируемость: ViewModel тестируется как чистый Kotlin/Swift-код без Android Instrumented Test.
MVVM закрывает 70% потребностей. Остальные 30% — где нужна строгая изоляция фич, масштабирование команды, сложный flow управления состоянием.
Clean Architecture: когда MVVM недостаточно
Добавляет слои поверх MVVM:
Domain-слой — бизнес-логика, независимая от платформы. UseCase (или Interactor) содержит одно бизнес-правило: GetUserOrdersUseCase, PlaceOrderUseCase. Зависит только от интерфейсов (protocol/interface), не от конкретных реализаций.
Data-слой — реализация репозиториев. OrderRepositoryImpl реализует OrderRepository из domain. Знает про Retrofit, Room, UserDefaults. ViewModel не знает, откуда данные — из сети или кеша.
Presentation-слой — ViewModel + View. Знает о Domain, не знает о Data.
Dependency rule: зависимости направлены только внутрь. Domain не зависит ни от чего. Data и Presentation зависят от Domain.
Presentation → Domain ← Data
Это даёт возможность подменять реализацию: тест использует in-memory репозиторий вместо сетевого, интерфейс остаётся тем же.
Практическая оговорка: Clean Architecture добавляет файлы и слои. Для небольшого приложения это overhead. Оправдан от ~15 фич и при команде 3+ разработчиков.
BLoC для Flutter: предсказуемый поток состояний
BLoC (Business Logic Component) — стандартный паттерн в Flutter-сообществе. Библиотека flutter_bloc реализует его через два типа: Bloc (Event → State) и Cubit (State без Events, только методы).
Bloc обрабатывает Event и эмитирует новый State через on<EventType> хендлеры. Состояние иммутабельно — новый объект на каждое изменение. BlocBuilder перерисовывает только ту часть дерева, где изменился state.
// Event
abstract class CartEvent {}
class AddItemToCart extends CartEvent {
final String productId;
AddItemToCart(this.productId);
}
// State
abstract class CartState {}
class CartLoaded extends CartState {
final List<CartItem> items;
CartLoaded(this.items);
}
// Bloc
class CartBloc extends Bloc<CartEvent, CartState> {
CartBloc(this._cartRepository) : super(CartLoaded([])) {
on<AddItemToCart>(_onAddItem);
}
Future<void> _onAddItem(AddItemToCart event, Emitter<CartState> emit) async {
final current = state as CartLoaded;
final updated = await _cartRepository.addItem(event.productId);
emit(CartLoaded(updated));
}
}
Преимущество BLoC — тестируемость. blocTest из bloc_test пакета позволяет проверить: при таком-то Event, с таким-то начальным State, BLoC должен эмитировать такой-то State. Без UI, без моков для Flutter-фреймворка.
VIPER: для крупных iOS-проектов
VIPER (View, Interactor, Presenter, Entity, Router) — наиболее строгое разделение обязанностей для iOS. Каждый компонент имеет протокол и конкретную реализацию.
-
View — только UI, делегирует всё Presenter
-
Interactor — бизнес-логика, работа с сетью и данными
-
Presenter — посредник между View и Interactor, форматирует данные для View
-
Entity — модели данных (чистые структуры)
-
Router — навигация между модулями
Каждый модуль (экран или фича) — отдельный VIPER-модуль. Это исключает coupling между фичами и позволяет большим командам работать параллельно без конфликтов.
Цена: много файлов, много протоколов. Шаблонный код генерируется через Sourcery или кастомные Xcode-шаблоны. VIPER оправдан для приложений с 10+ разработчиками и 50+ экранами.
TCA (The Composable Architecture)
TCA от Point-Free — более современная альтернатива VIPER для iOS/macOS. Основные концепции: State (иммутабельное состояние фичи), Action (все возможные события), Reducer (State + Action → новый State + Effect), Store (хранит State, обрабатывает Actions).
Scope позволяет composable строить большие фичи из маленьких: родительский Reducer делегирует часть State дочернему. Каждая фича тестируется изолированно через TestStore с точным контролем над Effects.
TCA имеет крутую кривую обучения, но даёт предсказуемость, которую сложно получить другим способом: каждое изменение состояния — явный Action с конкретным источником.
Какой паттерн выбрать под вашу задачу?
Оценим проект за 1 день — подберём архитектуру с учётом размера команды, платформы и планов роста.
| Паттерн |
Платформа |
Команда |
Когда выбирать |
| MVVM |
iOS, Android, Flutter |
1–5 |
Стартовый стандарт, MVP, небольшие проекты |
| MVVM + Clean |
iOS, Android |
3–10 |
Средние проекты, тестируемость критична |
| BLoC |
Flutter |
2–8 |
Flutter с предсказуемым state management |
| VIPER |
iOS |
5–20 |
Крупные iOS-проекты, модульная архитектура |
| TCA |
iOS/macOS |
3–15 |
Строгая тестируемость, Swift Concurrency |
Универсального ответа нет. Архитектуру выбирают под размер команды, требования к тестируемости и горизонт поддержки приложения.
Что входит в нашу работу
-
Аудит текущей архитектуры (если приложение уже существует) — выявим узкие места и регрессионные зоны.
-
Проектирование модульной структуры с чёткими границами слоёв и правилами зависимостей.
-
Создание каркаса проекта (Scaffold) с внедрением DI, организации папок и настройки линтеров.
-
Написание юнит-тестов для слоя домена и ViewModel — минимум 80% покрытия ключевых use case.
-
Подготовка документации — архитектурные диаграммы, README с правилами модификации кода, инструкция для онбординга новых разработчиков.
-
Передача рабочего репозитория с CI-пайплайном (GitHub Actions / Bitrise), настроенным запуском тестов и статическим анализом.
Всё это входит в стоимость проектирования. Дополнительно — поддержка на этапе внедрения: консультации команды, code review первых pull request.
Что происходит без архитектуры
Типичный сценарий через 18 месяцев без архитектуры: 40% времени разработки уходит на дебаг регрессий. Новый разработчик разбирается в коде неделю перед тем, как сделать первый PR. Тесты не пишутся, «потому что сложно мокировать». Добавление новой фичи требует понимания половины кодовой базы.
Выбор архитектуры на старте — это инвестиция с возвратом через 3–6 месяцев. По нашим данным, правильно спроектированная архитектура с MVVM + Clean даёт в 3 раза меньше регрессий по сравнению с монолитным ViewController. А затраты на её внедрение окупаются за 2–3 спринта.
Согласно рекомендациям Apple по проектированию приложений, разделение ответственности — ключевой фактор устойчивости кода (https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaViewController.html).
Почему стоит доверить архитектуру профессионалам?
Неправильный выбор паттерна на старте ведёт к переписыванию половины кода через год. Мы видели десятки проектов, где попытка сэкономить на архитектуре оборачивалась многомесячным рефакторингом. У нас за плечами 10+ лет коммерческой разработки, опыт работы с приложениями от 1 до 50 разработчиков. Мы помогаем избежать типовых ошибок:
- Overengineering для простого MVP (назначаем MVVM, а не VIPER).
- Отсутствие dependency injection — подключаем Hilt/Koin/Dagger уже на старте.
- Игнорирование тестируемости — закладываем протоколы/интерфейсы с первого коммита.
Оценим ваш проект бесплатно — пришлите описание текущего приложения или идеи, и мы подберём оптимальную архитектуру за 1 день. Пишите в Telegram или на почту — в ответ вы получите архитектурную схему, план внедрения и смету.
Дополнительная таблица: сравнение затрат на внедрение
| Паттерн |
Время проектирования |
Количество файлов на 1 экран |
Время написания тестов |
| MVVM |
2–3 дня |
5–7 |
1 день |
| MVVM + Clean |
4–5 дней |
10–12 |
2 дня |
| BLoC |
3–4 дня |
6–8 |
1.5 дня |
| VIPER |
5–7 дней |
12–15 |
2.5 дня |
| TCA |
5–6 дней |
8–10 |
2 дня |
Время указано для команды из 2–3 разработчиков. С нашим шаблоном (generator) стартовый каркас готов за 1 день вне зависимости от выбранного паттерна.