Как Gradle спасает white label app от ручного хаоса Недавно я начал делать pet-проект на Kotlin Multiplatform: white label mobile app для Android и iOS с нативным UI. И почти сразу упёрся в вопрос: как собирать одно приложение под разные бренды? У каждого tenant могут быть свои: — applicationId / bundleId — app name — app icon — logo — ресурсы — env-конфигурации Сначала кажется, что всё просто: можно руками поменять пару значений и собрать нужную версию. Но в white label app такой подход быстро превращается в источник ошибок. Сегодня забыл поменять app icon. Завтра собрал не с тем app name. Потом случайно оставил не тот applicationId. И проблема уже не в коде, а в процессе сборки. Поэтому я начал выносить tenant-specific конфигурацию в Gradle convention plugin и управлять сборкой через Gradle properties. Если с Android всё было более-менее понятно, то с iOS мне впервые пришлось нормально столкнуться с Assets.xcassets. Сначала я пошёл по самому очевидному пути: начал добавлять все ресурсы прямо в iosApp/Assets.xcassets, а через tenant config просто выбирать нужные. Но довольно быстро понял, что при масштабировании это превратится в ад. Появится несколько tenant, у каждого свои app icon, logo, цвета и картинки. Общий Assets.xcassets начнёт превращаться в свалку, где легко ошибиться и сложно понять, что к какому бренду относится. В итоге пришёл к более управляемому варианту: для каждого tenant хранить свой Assets.xcassets, а через Gradle копировать нужные ресурсы в iOS-приложение при сборке. Важно: не полностью заменять весь Assets.xcassets приложения, а аккуратно дополнять его ресурсами конкретного tenant. Один из неочевидных моментов был связан как раз с Gradle task для подготовки iOS-ресурсов. Сначала кажется: ну зарегистрировал task — и всё. Но в KMP-проекте важно, в какой момент ты это делаешь. Ошибка была не в самой task, а в том, когда именно она конфигурируется. Для меня это был хороший reminder: Gradle — это не просто файл сборки, а отдельный слой со своим lifecycle, зависимостями и точками расширения. Главный вывод для себя: в white label app build logic — это не архитектурная красота, а способ не ошибаться руками при каждой сборке. Один tenant. Одна Gradle-команда. Один ожидаемый результат. И чем больше конфигураций появляется, тем меньше хочется держать это в голове.
Android Developer / Platform Engineer | Kotlin, Gradle, CI/CD, DevEx, Jetpack Compose
· 30.040 комментов