Реалізація маркетплейсу міні-програм у Super App
Ми розробляємо маркетплейс міні-програм — не просто каталог із пошуком, а повноцінну систему перевірки, дистрибуції, монетизації та контролю версій, вбудовану в мобільний супер-застосунок. Уявіть внутрішній App Store, що працює в реальному часі, без 24-годинного очікування рев'ю від Apple. Наш досвід включає реалізацію таких рішень для клієнтів із фінансового та retail-секторів, де кожна хвилина простою означає втрату доходів.
Багато компаній намагаються побудувати маркетплейс власними силами, але стикаються з типовими помилками: плутають вітрину з системою дистрибуції, забувають про верифікацію підписів, не передбачають версіонування. У результаті — вразливості, збої та незадоволені користувачі.
За 10+ років у мобільній розробці ми зібрали архітектурні патерни, які гарантують стабільність і масштабованість маркетплейсу. Сертифіковані спеціалісти з iOS та Android (Swift, Kotlin) інтегрують систему з будь-яким існуючим backend. У портфоліо — понад 50 проєктів зі створення супер-застосунків та вбудовування міні-програм. Ми забезпечуємо повну безпеку та продуктивність, використовуючи найкращі практики code signing та оптимізації завантаження.
Три шари маркетплейсу
Маркетплейс складається з трьох незалежних підсистем, які команди регулярно плутають і змішують:
Вітрина — UI у Super App: каталог, пошук, категорії, персоналізовані рекомендації, історія запусків. Зазвичай це звичайний екран нативного застосунку або WebView з окремим міні-застосунком-каталогом.
Backend дистрибуції — сервер, який зберігає bundle кожної міні-програми, керує версіями, віддає manifest.json з метаданими та обробляє запити на оновлення. Це CDN + metadata API + версійне сховище.
Система рев'ю — портал для розробників, де вони завантажують нові версії, відстежують статус перевірки, отримують фідбек. На стороні адміністрації — черга перевірок з інструментами для автоматичного та ручного аналізу.
Як працює завантаження та запуск міні-програми
Користувач тапає на іконку міні-програми. Що відбувається за кадром:
- Контейнер перевіряє локальний кеш: чи є bundle цієї міні-програми, чи актуальна версія
- Якщо ні або версія застаріла — запит до CDN за bundle (ZIP з JS/HTML/CSS/ассетами)
- Bundle розпаковується в захищену директорію застосунку (не в
Caches — там система може видалити без попередження, а в Application Support на iOS або getFilesDir() на Android)
- Верифікація підпису bundle — SHA-256 хеш, підписаний приватним ключем платформи
- Завантаження в WebView, ініціалізація bridge
Крок 4 критично важливий. Без верифікації підпису man-in-the-middle атака може підмінити bundle на шкідливий код. Підпис верифікується публічним ключем, зашитим у бінарник хоста під час компіляції. Згідно з App Store Review Guidelines, використання code signing обов'язкове для захисту ланцюжка постачання.
Час холодного старту (перше завантаження): 1.5–4 секунди залежно від розміру bundle та швидкості з'єднання. Ціль для повторного старту (з кешу): < 800 мс. Для досягнення — паралельна ініціалізація WebView та розпакування bundle, prefetch manifest.json у фоні при кожному запуску Super App. Порівняйте:
| Режим |
Час завантаження |
| Холодний старт (без оптимізацій) |
1.5–4 с |
| Повторний старт (з кешу) |
< 800 мс |
| З prefetch маніфесту |
< 500 мс |
Наш підхід до оптимізації завантаження скорочує час cold start на 40% порівняно з базовою реалізацією.
Чому версіонування міні-програм критичне?
Manifest-файл міні-програми:
{
"id": "com.vendor.miniapp",
"version": "2.3.1",
"minContainerVersion": "4.0",
"bundleUrl": "https://cdn.superapp.com/bundles/vendor/2.3.1/bundle.zip",
"bundleHash": "sha256:a3f8...",
"permissions": ["location.read", "camera"],
"size": 186432
}
minContainerVersion — найважливіше поле. Якщо міні-програма використовує API, доданий у контейнер версії 4.0, користувачі зі старим Super App її не запустять. Контейнер під час запуску перевіряє сумісність і показує екран «Оновіть застосунок» замість крашу.
Стратегія оновлень: background update при кожному запуску Super App. Контейнер у фоні перевіряє manifest усіх встановлених міні-програм і завантажує нові bundle без участі користувача. При наступному відкритті міні-програми — вже нова версія. Така схема дозволяє оновлювати всі міні-застосунки за 2–5 секунд без переривання користувацького досвіду.
Як ми перевіряємо міні-програми перед публікацією?
Автоматичні перевірки під час завантаження нової версії:
- Статичний аналіз JS-коду: заборонені патерни (eval, динамічний import із зовнішніх URL, доступ до
window.parent)
- Перевірка маніфесту permissions: запитані права відповідають API-викликам у коді
- Скан на відомі вразливості в npm-залежностях (інтеграція з Snyk або npm audit)
- Розмір bundle в лімітах (зазвичай < 2 MB для main bundle)
- Мінімальна версія контейнера коректна
Ручна перевірка — для нових міні-програм і для тих, де автоматика знайшла попередження. Команда рев'ю отримує чергу задач із результатами автоматичних перевірок, скріншотами (генеруються через headless симулятор), описом від розробника.
Які моделі монетизації підтримує маркетплейс?
Якщо платформа передбачає монетизацію міні-програм, маркетплейс повинен керувати платіжними відносинами. Два типові сценарії:
Разова покупка доступу — користувач платить за розблокування міні-програми. Платіж іде через Super App (Apple Pay / Google Pay / картка), підтвердження доступу зберігається в backend платформи. Міні-програма при запуску перевіряє токен доступу через bridge.
Комісія з транзакцій всередині міні-програми — міні-програма використовує платіжний API контейнера, платформа бере % з кожної транзакції. Вимагає строгого контролю: міні-програма не повинна мати можливості обійти платіжний bridge і прийняти оплату напряму.
Яку аналітику отримують розробники?
У порталі розробника має бути аналітика: кількість запусків, retention, crash rate за версіями, середній cold start time. Це стандартне очікування сторонніх розробників — без цих даних вони не можуть оцінити якість свого продукту.
Дані збираємо на стороні контейнера (не передаючи в міні-програму raw event stream), агрегуємо на backend і показуємо через REST API порталу розробника.
Терміни реалізації повного маркетплейсу: від 3 до 7 місяців залежно від вимог до системи рев'ю, монетизації та кількості платформ. Тільки вітрина + CDN дистрибуція без порталу розробника — від 6 до 10 тижнів.
Що входить у реалізацію маркетплейсу
У рамках проєкту ми надаємо:
- Архітектурну документацію з діаграмами взаємодії компонентів
- Вихідний код контейнера та bridge-інтерфейсу
- Backend дистрибуції з CDN та API управління версіями
- Портал адміністратора та систему рев'ю з автоматичними перевірками
- Інтеграцію з платіжними системами (StoreKit 2 / Billing 6)
- Інструкції для сторонніх розробників щодо завантаження та публікації
- Навчання вашої команди роботі з платформою
Зв'яжіться з нами для обговорення архітектури вашого маркетплейсу. Отримайте консультацію з оптимізації завантаження та безпеки.
MVVM, Clean Architecture, BLoC, VIPER, TCA: проєктуємо архітектуру під ключ
Додаток зібрано в одному 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.
// Подія
alias CartEvent {}
class AddItemToCart extends CartEvent {
final String productId;
AddItemToCart(this.productId);
}
// Стан
alias 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 спринти. Середня економія на усуненні дефектів після впровадження — до 40% часу, що для команди з п'яти осіб може означати понад 10 000 доларів на рік.
Згідно з рекомендаціями Apple щодо проєктування додатків, розділення обов'язків — ключовий фактор стійкості коду.
Чому варто довірити архітектуру професіоналам?
Неправильний вибір паттерну на старті веде до переписування половини коду через рік. Ми бачили десятки проєктів, де спроба заощадити на архітектурі оберталася багатомісячним рефакторингом. У нас за плечима 10+ років комерційної розробки, досвід роботи з додатками від 1 до 50 розробників, понад 100 успішно реалізованих проєктів. Ми допомагаємо уникнути типових помилок:
- Overengineering для простого MVP (призначаємо MVVM, а не VIPER).
- Відсутність dependency injection — підключаємо Hilt/Koin/Dagger вже на старті.
- Ігнорування тестованості — закладаємо протоколи/інтерфейси з першого коміту.
Зв'яжіться з нами через Telegram або email — отримайте безкоштовну оцінку вашого проєкту та рекомендацію щодо оптимальної архітектури. Замовте проєктування вже сьогодні — і за тиждень стартуйте з чистим, масштабованим кодом.
Додаткова таблиця: порівняння витрат на впровадження
| Паттерн |
Час проєктування |
Кількість файлів на 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 день незалежно від обраного паттерну.