Реализация системы мини-программ (Mini Programs) внутри мобильного приложения
Если super app — это платформа целиком, то система мини-программ — конкретный технический компонент этой платформы. Здесь речь о том, как именно мини-программа запускается внутри хост-приложения, как она получает доступ к нативным API, как обновляется без релиза в App Store, и как изолируется от других программ и от хоста.
Runtime для мини-программ
Два кардинально разных подхода.
WebView-based. Мини-программа — это веб-приложение (React, Vue, или кастомный DSL как у WeChat WXML/WXSS). Запускается в изолированном WKWebView (iOS) или WebView (Android). Стандартные веб-технологии, низкий порог входа для партнёров, кроссплатформенность кода мини-программы. Ограничения: производительность ниже нативной, нет доступа к сложным нативным API без Bridge.
Native plugin-based. Мини-программа — скомпилированный нативный код (Android: DEX через DexClassLoader; iOS: compile-time Swift Package). Нативная производительность, полный доступ к API через контролируемые интерфейсы. Ограничения: App Store запрещает загрузку исполняемого кода на iOS, поэтому на iOS нативные плагины должны быть включены в бинарник при сборке.
На практике используем гибрид: базовые партнёрские сервисы — WebView, собственные критичные мини-программы — нативные плагины.
Формат пакета мини-программы
Мини-программа дистрибутируется как zip-архив с манифестом:
{
"id": "com.partner.loans",
"version": "2.3.1",
"minHostVersion": "3.0.0",
"entryPoint": "index.html",
"permissions": ["payment", "geolocation"],
"allowedDomains": ["api.partner.com", "cdn.partner.com"],
"signature": "sha256:abc123..."
}
При загрузке хост: верифицирует подпись архива (RSA-PSS с публичным ключом партнёра), проверяет minHostVersion совместимость, проверяет permissions против списка разрешённых для данного партнёра, распаковывает в изолированную директорию. Запуск — только после успешной верификации.
Bridge API: дизайн и безопасность
Bridge — единственная точка контакта между мини-программой и хостом. Архитектура запроса-ответа:
На стороне мини-программы (JS):
MiniAppBridge.call('payment.pay', {
orderId: 'order-123',
amount: 99.99,
currency: 'USD'
}).then(result => {
// result.transactionId
}).catch(err => {
// err.code, err.message
});
На стороне хоста (нативный код) Bridge:
- Получает вызов через
WKScriptMessageHandler.userContentController(_:didReceive:)(iOS) или@JavascriptInterfaceметод (Android) - Парсит
methodиparams - Проверяет: есть ли у этой мини-программы разрешение вызвать
payment.pay - Если да — выполняет нативный код (показывает Payment UI, обрабатывает транзакцию)
- Возвращает результат через
webView.evaluateJavaScript("MiniAppBridge._resolve(requestId, result)")
Каждый метод Bridge имеет явный список разрешений. Вызов метода без нужного разрешения → синхронная ошибка PERMISSION_DENIED. Разрешения выдаются при регистрации партнёра, хранятся на сервере, кешируются в хосте.
Изолированное хранилище и сессии
Каждая мини-программа получает namespace в локальном хранилище: ключи вида {mini_program_id}:{key}. Прямого доступа к SQLite или SharedPreferences хоста — нет. Доступ только через Bridge методы storage.set / storage.get / storage.remove с принудительным namespace.
WebView localStorage тоже изолирован: каждая мини-программа запускается с WKWebViewConfiguration с отдельным WKWebsiteDataStore.nonPersistent() или именованным persistent store. На Android — WebStorage с кастомным директорием и запрет пересечения origin.
Сессия пользователя. Мини-программа получает access token только через Bridge auth.getToken(). Токен выдаётся хостом на 15 минут, привязан к mini_program_id, scope ограничен. Мини-программа не видит master JWT пользователя.
Обновление мини-программ
Обновление — без ревью в App Store. Последовательность:
- При запуске мини-программы (или фоново по расписанию) хост проверяет актуальную версию через
GET /mini-programs/{id}/version - Если сервер возвращает более новую версию — загружаем архив в фоне
- Верифицируем подпись нового архива
- При следующем запуске мини-программы — активируем новый пакет
- Предыдущая версия — в backup (для rollback при необходимости)
Принудительное обновление: если minHostVersion нового пакета несовместима с текущим хостом — показываем экран «Доступно обновление приложения» вместо запуска мини-программы.
Отладка и DevTools для партнёров
Разработчику мини-программы нужен удобный инструментарий. Предоставляем:
- Simulator mode: локальный сервер (
localhost:8080) как источник мини-программы вместо CDN — хост читает файлы напрямую без верификации подписи (только в debug build) - Bridge Inspector: логирование всех Bridge-вызовов в debug консоль Xcode / Android Studio Logcat
- Mock Bridge: JS-библиотека (
mini-program-bridge-mock) для тестирования в браузере без хоста
Кейс. Партнёрская экосистема маркетплейса: 8 партнёров, 23 активных мини-программы (12 WebView, 11 нативных плагинов на Android / compile-time на iOS). Bridge API: 55 методов. Среднее время холодного запуска мини-программы (первый за сессию) — 380 мс на iPhone 14. Тёплый запуск (возврат после паузы) — 80 мс. Обновление фоново: 70% пользователей получают новую версию мини-программы без перезапуска хоста.
Сроки реализации системы мини-программ
| Компонент | Ориентировочные сроки |
|---|---|
| WebView runtime + базовый Bridge (20 методов) | 8–12 недель |
| Маркетплейс + подпись + обновление | +4–6 недель |
| Нативный plugin runtime (Android) | +4–8 недель |
| Partner SDK + DevTools | +4–6 недель |
Стоимость рассчитывается индивидуально после анализа требований к Bridge API, числу партнёров и требованиям безопасности.







