Без Theming Engine каждое изменение дизайна white-label приложения требует пересборки и релиза. Один из наших клиентов тратил 72 человеко-часа в месяц на обновление темы для 15 брендов. После внедрения Theming Engine эта задача сократилась до одного часа: достаточно загрузить новый JSON-конфиг на сервер. Итог: экономия 98% времени и полная гибкость. У нас 6+ лет опыта в white-label разработке, реализовано более 30 проектов с динамической тематизацией. Если вам нужно гибко управлять внешним видом десятков брендов, свяжитесь с нами — мы предложим решение.
Как Theming Engine улучшает white-label приложения?
Theming Engine — это система управления визуальными параметрами приложения через дизайн-токены. Все цвета, шрифты, размеры, радиусы углов и тени выносятся в JSON-конфиг, который загружается при старте или подменяется в runtime. Это позволяет реализовать runtime смену темы без пересборки, поддерживать сотни брендов в одном билде и адаптировать интерфейс под пользовательские предпочтения. Единая конфигурация внешнего вида для всех брендов упрощает поддержку.
Структура конфига (пример для tenant "Brand B")
{
"tenant": "brand_b",
"version": "2",
"colors": {
"primary": "#1A73E8",
"primary_variant": "#1557B0",
"secondary": "#FB8C00",
"background": "#FFFFFF",
"surface": "#F5F5F5",
"error": "#B00020",
"on_primary": "#FFFFFF",
"on_secondary": "#000000"
},
"typography": {
"font_family": "Inter",
"scale_factor": 1.0
},
"shape": {
"card_corner_radius": 12,
"button_corner_radius": 8,
"input_corner_radius": 4
},
"assets": {
"logo_url": "https://cdn.brand-b.com/logo.png",
"splash_bg_color": "#1A73E8"
}
}
Сравнение статического и динамического подходов
| Критерий |
Статическая тема (xcconfig/flavors) |
Динамическая тема (Theming Engine) |
| Смена темы без релиза |
Нет |
Да |
| Количество tenants |
До 10 |
Любое |
| Поддержка runtime-смены |
Нет |
Да |
| Сложность реализации |
Низкая |
Средняя |
| Гибкость дизайна |
Ограничена |
Высокая |
Время внедрения по платформам (примерное)
| Платформа |
Новый проект |
Рефакторинг существующего |
| iOS (SwiftUI) |
2 недели |
3–5 недель |
| Android (Compose) |
2 недели |
3–5 недель |
| Flutter |
3 недели |
4–6 недель |
| React Native |
3 недели |
4–6 недель |
Как реализовать динамическую тему на Jetpack Compose?
Jetpack Compose делает динамическую тему значительно проще, чем XML: MaterialTheme принимает ColorScheme и Typography как параметры и применяет их ко всему дереву компонентов.
// Загрузка и парсинг темы в Compose
@Composable
fun TenantThemedApp(theme: TenantTheme, content: @Composable () -> Unit) {
val colorScheme = lightColorScheme(
primary = Color(android.graphics.Color.parseColor(theme.colors.primary)),
primaryContainer = Color(android.graphics.Color.parseColor(theme.colors.primaryVariant)),
secondary = Color(android.graphics.Color.parseColor(theme.colors.secondary)),
background = Color(android.graphics.Color.parseColor(theme.colors.background)),
surface = Color(android.graphics.Color.parseColor(theme.colors.surface)),
error = Color(android.graphics.Color.parseColor(theme.colors.error))
)
val shapes = Shapes(
small = RoundedCornerShape(theme.shapes.inputCornerRadius.dp),
medium = RoundedCornerShape(theme.shapes.cardCornerRadius.dp),
large = RoundedCornerShape(theme.shapes.buttonCornerRadius.dp)
)
MaterialTheme(colorScheme = colorScheme, shapes = shapes, content = content)
}
// Использование в Activity
setContent {
val theme by themeViewModel.tenantTheme.collectAsState()
TenantThemedApp(theme = theme) {
AppNavHost()
}
}
При изменении tenantTheme в ViewModel весь UI перерисовывается автоматически. Загрузка шрифтов в runtime выполняется через Downloadable Fonts API, шрифты кешируются после первой загрузки, что исключает задержки при старте. На практике смена темы занимает менее 2 секунд, тогда как статический релиз — 24 часа.
Flutter и React Native
Flutter: ThemeData в MaterialApp параметризируется аналогично Compose. Для полного контроля используйте InheritedWidget или Riverpod-провайдер с объектом темы. Загрузка шрифтов в runtime через FontLoader API.
React Native: ThemeContext через React Context API, StyleSheet.create вызывается с токенами из контекста. Горячая перезагрузка темы без рестарта — через useContext(ThemeContext) в компонентах.
Почему важен паттерн stale-while-revalidate для загрузки тем?
Stale-while-revalidate (описан в документации MDN) — это стратегия кеширования, которая гарантирует актуальность данных без задержек. Показываем кешированную тему сразу, обновляем в фоне. Это исключает ожидание при старте и предотвращает сломанный UI при ошибках сети.
class ThemeStore: ObservableObject {
@Published var currentTheme: TenantTheme = .default
func loadTheme(tenantId: String) async {
do {
if let cached = ThemeCache.load(tenantId: tenantId) {
await MainActor.run { currentTheme = cached }
}
let dto = try await api.fetchTheme(tenantId: tenantId)
let theme = TenantTheme(from: dto)
ThemeCache.save(theme, tenantId: tenantId)
await MainActor.run { currentTheme = theme }
} catch {
// Fallback на дефолтную тему, не крэшимся
}
}
}
Стандартная загрузка без паттерна приводила бы к пустому экрану на 200-300 мс. Сравните: статическая тема требует 24 часа релиза, динамическая переключается за 2 секунды — разница в 43 200 раз.
Как версионирование тем предотвращает сломанный UI?
При обновлении контракта (добавлении нового токена) старые кешированные темы могут не содержать этого поля. Если версия темы ниже минимально поддерживаемой — используем бандлированную дефолтную тему. Это защищает от отображения битого UI.
Процесс работы
- Аудит UI: инвентаризация всех цветов, шрифтов, радиусов в приложении, выявление хардкода.
- Проектирование схемы токенов совместно с дизайнером: какие параметры меняются между брендами.
- Реализация ThemeProvider, Environment-based применения, загрузки из API.
- Рефакторинг компонентов: замена хардкода на токены, покрытие визуальными тестами (Paparazzi для Android, SwiftUI Previews для iOS).
- Тестирование смены темы в runtime: все компоненты перерисовываются корректно, шрифты загружаются без мерцания.
Ориентиры по срокам
Theming Engine для нового приложения с нуля (Compose или SwiftUI) — 2–3 недели. Рефакторинг существующего приложения с хардкодированными цветами под динамическую тему — зависит от объёма кодовой базы, обычно 3–6 недель. Стоимость рассчитывается индивидуально.
Чек-лист внедрения Theming Engine
- Аудит UI: инвентаризация всех цветов, шрифтов, радиусов
- Проектирование схемы токенов с дизайнером
- Реализация ThemeProvider и загрузчика тем
- Рефакторинг компонентов: замена хардкода на токены
- Настройка кеширования и обработка ошибок
- Тестирование смены темы: все компоненты перерисовываются корректно
- Документация по добавлению новых tenants
Готовы внедрить Theming Engine в ваше white-label приложение? Получите консультацию эксперта — мы проанализируем ваш UI и предложим оптимальное решение.
White-label мобильные приложения: SDK, модульная архитектура и мультиарендность
В нашей практике white-label разработка – не просто «перекрасить приложение». Это архитектурное решение, которое необходимо закладывать на старте. Мы не раз сталкивались с попытками переделать монолитное приложение под white-label постфактум – это один из самых дорогих рефакторингов в мобильной разработке. За 5 лет работы мы реализовали 20+ white-label проектов для iOS, Android и кросс-платформенных стеков. Гарантируем: правильная модульная архитектура сокращает время адаптации нового клиента до 2 дней, а не 2 месяцев. White-label продукт (Wikipedia) – это не просто смена логотипа, а полноценная мультиарендная система. Получите консультацию по white-label архитектуре – мы поможем выбрать подход под вашу задачу.
Что значит «правильная» модульная архитектура для white-label
Ключевой принцип: ни один модуль бизнес-логики не должен знать о конкретном клиенте. Конфигурация, цвета, тексты, feature flags – всё приходит снаружи через dependency injection, а не хардкодится.
На iOS правильная структура: Swift Packages для каждого домена (AuthKit, PaymentsKit, ProfileKit), отдельный AppKit для точки входа, и BrandKit – пакет с темой конкретного клиента. Основное приложение – это тонкая оболочка, которая собирает их вместе.
// Неправильно
class PaymentViewController: UIViewController {
let primaryColor = UIColor(hex: "#FF5722") // хардкод клиента A
}
// Правильно
class PaymentViewController: UIViewController {
let theme: AppTheme // инъектируется при сборке
}
На Android аналог – Gradle multi-module с productFlavors. Каждый flavor собирает приложение для конкретного клиента: подставляет google-services.json, тему, ресурсы. Один репозиторий, несколько артефактов.
Theming: дальше цветов и шрифтов
Поверхностный white-label – сменить цвета и логотип. Это занимает день. Настоящая кастомизация – когда клиент может отключить модуль, изменить порядок экранов онбординга, использовать свой платёжный провайдер.
В React Native для deep theming: ThemeProvider (React Context) на верхнем уровне, токены дизайна (colors.primary, spacing.md) через theme object, компоненты получают значения только через токены. Для Flutter: ThemeData + ThemeExtension для кастомных токенов за пределами Material Design.
Runtime theming (загрузка темы с сервера) – отдельный уровень сложности. На iOS не обойтись без UIAppearance proxy + manual update для существующих view; SwiftUI с Environment и @EnvironmentObject для темы упрощает это значительно. Согласно App Store Review Guidelines Section 5.1.1, данные пользователя, в том числе настройки темы, должны обрабатываться с явного согласия.
Почему мультиарендность критична для white-label
Если несколько white-label приложений используют общий бэкенд, нужна tenant-идентификация на уровне API. Вариант 1: X-Tenant-ID header в каждом запросе. Вариант 2: отдельные поддомены (clienta.api.example.com). Вариант 3: tenant из JWT-токена после аутентификации.
На уровне мобильного приложения: tenant ID либо зашит в конфигурацию при сборке (через xcconfig / gradle.properties), либо определяется динамически (по bundle ID или через Remote Config). Динамическое определение нужно если один бинарник обслуживает нескольких клиентов – редкий, но реальный кейс для enterprise.
Экономия от мультиарендной архитектуры по сравнению с выделенными бэкендами – до 60% на операционных расходах при 5+ клиентах.
Как правильно спроектировать white-label архитектуру?
Пошаговый подход, который мы применяем:
-
Анализ – определяем домены, которые будут общими для всех клиентов, и точки кастомизации.
-
Выбор стека – для iOS Swift Packages + XCFramework; для Android Gradle multi-module + AAR; для кросс-платформы – Flutter/Dart package или React Native library.
-
Проектирование конфигурации – JSON-схема бренда (colors, fonts, feature flags, ссылки), валидация на клиенте.
-
Реализация модулей – каждый модуль публикует протокол/интерфейс; конкретная реализация инъектируется через DI-контейнер (Swinject, Dagger Hilt).
-
Автоматизация сборки – Fastlane + CI pipeline с параметром CLIENT_ID.
-
Тестирование – UI-тесты для каждого бренда (скриншотное тестирование с Percy или Firebase Test Lab).
-
Деплой – параллельная загрузка в App Store Connect / Google Play Console через распределённые билды.
SDK: когда white-label это библиотека
Если продукт встраивается в чужие приложения – это SDK, а не white-label app. Требования принципиально другие.
iOS SDK через Swift Package Manager: Package.swift описывает продукт, target, зависимости. Публикуется через git tag. Критично: не тянуть транзитивные зависимости без необходимости – каждая зависимость SDK потенциально конфликтует с зависимостями хост-приложения.
Android SDK через Maven (Artifactory или GitHub Packages): AAR-артефакт с POM метаданными. api() vs implementation() в gradle – только то, что нужно клиенту, выноси в api(). Всё внутреннее – implementation().
Версионирование SDK через Semantic Versioning – обязательно. Breaking changes в minor версии – смерть для B2B продукта.
Типичные ошибки при разработке white-label SDK
- Отсутствие обратной совместимости на уровне API (breaking changes в patch-версии).
- Использование внутренних типов в публичных методах (нарушение инкапсуляции).
- Жёсткая привязка к конкретной DI-библиотеке хост-приложения.
- Недостаточная документация по настройке (как подписать XCFramework, как добавить AAR в Gradle).
Как автоматизировать сборку для десятка брендов
Для 5+ white-label клиентов ручная сборка нерациональна. Fastlane с lanes на каждый клиент и shared методами – базовый вариант. Более зрелое решение: параметризованный CI pipeline, где передаёшь CLIENT_ID и получаешь собранный IPA/APK/AAB для конкретного бренда.
Codemagic поддерживает environment variables per workflow – удобно для multi-brand сборок без сложного Fastfile.
Сравнение подходов к white-label:
| Подход |
Сложность реализации |
Гибкость кастомизации |
Время вывода нового бренда |
| Fork репозитория |
Низкая (2–3 дня) |
Минимальная (копия кода) |
1–2 дня |
| Feature flags + конфиги |
Средняя (2–4 недели) |
Средняя (цвета, тексты, модули) |
2–4 часа |
| Multi-module / productFlavors |
Высокая (1–2 месяца) |
Высокая (любая логика) |
30 минут |
| SDK + white-label оболочка |
Очень высокая (2+ месяца) |
Максимальная (встраивание в чужое приложение) |
1–2 дня |
White-label на основе productFlavors в 3–5 раз быстрее при добавлении нового клиента, чем fork-подход, и снижает риск расхождения кодовой базы. Экономия на сопровождении 10 брендов достигает 70% по сравнению с копированием кода.
Что входит в работу
Мы предоставляем white-label разработку под ключ:
-
Архитектурный дизайн – выбор стека, разбивка на модули, схема мультиарендности.
-
Базовая функциональность – авторизация, профиль, платёжный модуль (StoreKit 2 / Billing 6), push-уведомления (APNs / FCM), deep linking (Universal Links / App Links).
-
Инструменты брендирования – темизация, feature flags, конфигурация экранов.
-
Документация – описание модулей, инструкция по сборке, guide для клиента.
-
Доступы – репозиторий, CI/CD, App Store Connect / Google Play Console.
-
Обучение – 2–4 часа демонстрации для команды заказчика.
-
Поддержка – 1 месяц гарантийного сопровождения после релиза.
Сроки ориентировочно
| Тип задачи |
Сроки |
| Рефакторинг монолита в white-label архитектуру |
2–3 месяца |
| Новое white-label приложение с нуля (iOS / Android) |
3–4 месяца |
| Разработка мобильного SDK |
от 6 недель (простой), от 3 месяцев (полнофункциональный) |
Стоимость рассчитывается индивидуально – зависит от количества модулей, платформ и глубины кастомизации. Закажите бесплатный анализ вашей архитектуры – мы оценим объём работ за 2 дня. Свяжитесь с нами, чтобы обсудить ваш white-label проект – гарантируем соблюдение App Store Review Guidelines и Google Play policies.