Сборка APK и IPA из одного кода на FireMonkey: подводные камни
FireMonkey от Embarcadero позиционируется как среда для разработки кросс-платформенных приложений, где одна и та же кодовая база компилируется под Windows, macOS, Linux, Android и iOS. Для десктопных систем процесс относительно прямолинеен: достаточно выбрать целевую платформу и нажать «Сборка». С мобильными операционными системами ситуация заметно усложняется, поскольку Android и iOS требуют совершенно разных инструментов, сертификатов и подходов к упаковке.
Именно на этапе превращения общего исходного кода в готовые дистрибутивы разработчик сталкивается с массой нюансов. Часть из них связана с самим фреймворком, часть — с требованиями магазинов приложений и операционных систем. Понимание этих различий помогает заранее спланировать архитектуру проекта и избежать переделок в последний момент.
Архитектура проекта FireMonkey для мобильных платформ
При создании проекта под несколько мобильных платформ в Delphi или RAD Studio формируется единый файл проекта с условными блоками компиляции. Директивы {$IFDEF MSWINDOWS}, {$IFDEF ANDROID}, {$IFDEF IOS} позволяют изолировать платформенно-зависимый код, сохраняя общую бизнес-логику в общих модулях. Такой подход снижает дублирование и упрощает сопровождение, но требует дисциплины при работе с формами и компонентами, доступными только на одной платформе.
Файлы ресурсов и медиа лучше хранить в одной папке с разделением по подкаталогам, поскольку менеджер проекта FireMonkey поддерживает относительные пути. Для мобильных сборок критично заранее определить набор форм, шрифтов и изображений, так как перенос лишних ресурсов увеличивает размер итогового пакета и замедляет запуск приложения. Грамотная архитектура экономит время на этапе финальной компоновки.
Важно учитывать, что FireMonkey использует разные форматы форм при таргетировании на разные ОС. Для iOS лучше сразу проектировать интерфейс с учётом Safe Area и особенностей навигации, тогда как для Android — ориентироваться на Material-подобные паттерны. Общий стиль можно задать через TStyleBook, но визуальная логика всё равно будет отличаться.
Особенности сборки Android-пакета
APK или AAB формируется через SDK Manager и утилиты, поставляемые вместе с RAD Studio. На этом пути возникает несколько типичных сложностей: версия Android SDK может конфликтовать с установленной JDK, а путь к инструментам платформы должен быть прописан в системных переменных. Любая несовместимость на этом этапе превращает сборку в лотерею и отнимает часы рабочего времени.
Отдельного внимания заслуживает файл манифеста и разрешения, которые приложение запрашивает у системы. По умолчанию FireMonkey включает базовый набор, но для работы с камерой, геолокацией или уведомлениями необходимо вручную добавить нужные permissions. Здесь часто допускают ошибку, пытаясь получить доступ к функциям устройства через сторонние компоненты без обновления манифеста.
Подписание пакета — ещё один камень преткновения. Для отладочной версии используется автоматически сгенерированный debug-ключ, но релизная сборка требует собственного хранилища ключей с надёжным паролем и сроком действия. Если ключ утерян, обновить приложение в Google Play тем же идентификатором пакета уже не получится. Поэтому резервное копирование keystore — обязательная практика для каждого Android-разработчика.
Тонкости упаковки iOS-приложения
Для iOS FireMonkey требует наличия macOS с установленным Xcode и командной строкой PAServer, через которую происходит удалённая компиляция. Без связки этих компонентов собрать IPA невозможно — даже если у вас есть действующий Apple Developer аккаунт. Это первое принципиальное отличие от Android, где сборка выполняется локально на Windows или Linux.
Профили провижинга и сертификаты разработчика создаются на портале Apple Developer и привязываются к уникальному Bundle Identifier. Любое несоответствие между профилем и идентификатором приложения приводит к ошибкам codesign. Для разных целей — разработка, тестирование через TestFlight, публикация в App Store — нужны разные типы профилей, что требует аккуратного управления ими.
Архитектура процессора накладывает дополнительные ограничения: начиная с iOS 11, Apple требует 64-битные сборки, а современные устройства работают на ARM64. FireMonkey умеет собирать под нужную архитектуру, но иногда сторонние библиотеки поставляются только для устаревших ARMv7, и тогда приходится искать альтернативы или отказываться от них. Этот вопрос часто всплывает на этапе интеграции SDK аналитики или платёжных систем.
Управление зависимостями и библиотеками
Подключение сторонних модулей в проекте FireMonkey традиционно выполняется через менеджер пакетов GetIt или вручную путём добавления DCU-файлов. На мобильных платформах далеко не все библиотеки Delphi имеют готовые сборки. Часть компонентов приходится компилировать отдельно под каждую цель, отслеживая совместимость версий и разрядность.
Особенно остро проблема зависимостей ощущается при использовании нативных API: Firebase, Google Maps, CoreLocation, In-App Purchases. Для каждой из них существуют FireMonkey-обёртки, но они не всегда поспевают за обновлениями исходных SDK. В результате после релиза Firebase или Apple может перестать принимать старые версии, и проект потребует срочного обновления. Практические примеры интеграции таких сервисов в реальных приложениях собраны в каталоге проектов.
Контроль размера итогового пакета не менее важен. Android ограничивает APK 100 МБ для основного файла и требует выноса крупных ресурсов в OBB, тогда как iOS традиционно более лоялен к размеру, но строго следит за архитектурой и подписью. Неоптимизированные изображения и лишние локали быстро раздувают дистрибутив и ухудшают пользовательский опыт.
Различия в разрешениях и конфигурациях
FireMonkey позволяет задавать отдельные конфигурации для каждой целевой платформы через менеджер сборок. Это удобно для управления ключами API, адресами серверов и параметрами отладки. Однако при переносе изменений между конфигурациями легко запутаться: например, случайно оставить продакшен-ключ в отладочной сборке iOS или наоборот.
Разрешения экрана и ориентация устройства — ещё один источник неожиданностей. На Android существует огромное разнообразие размеров экранов и плотностей, и без качественной адаптивной вёрстки интерфейс «поедет» на нестандартных устройствах. iOS отличается более предсказуемым набором разрешений, но вводит собственные ограничения через Dynamic Island и Safe Area на новых моделях.
Темы оформления также требуют раздельного подхода. Стиль, идеально выглядящий на iPhone, может оказаться плохо читаемым на Android с его Material-палитрой. FireMonkey предлагает TStyleBook, но создавать отдельные наборы стилей под каждую платформу приходится вручную, если нужна действительно нативная визуальная подача.
Тестирование и отладка на разных устройствах
Эмуляторы RAD Studio дают лишь общее представление о работе приложения. Реальное тестирование требует физических устройств — и здесь кросс-платформенная разработка проверяется по-настоящему. Android позволяет устанавливать APK по USB с включённой отладкой, а iOS требует регистрации устройства в Apple Developer и привязки к профилю провижинга.
Отладка через IDE работает на обеих платформах, но скорость и стабильность подключения различаются. На Android часто возникают разрывы соединения при переключении между Wi-Fi сетями, тогда как iOS через PAServer ведёт себя стабильнее, но требует постоянного macOS-хоста. Это влияет на скорость итераций при исправлении багов и планирование рабочего времени.
Логирование и сбор краш-репортов тоже устроены по-разному. Android собирает данные через Logcat, iOS — через Console и Crashlytics. FireMonkey предлагает собственные средства логирования, но для продакшена лучше интегрировать специализированные сервисы. Без этого анализ причин падений у конечных пользователей превращается в гадание.
Сравнение ключевых этапов сборки APK и IPA
| Этап | APK (Android) | IPA (iOS) |
|---|---|---|
| Среда сборки | Локально, Windows/Linux/macOS | Только macOS через PAServer |
| Инструменты | Android SDK + JDK | Xcode + Apple Developer аккаунт |
| Идентификатор | Package Name | Bundle Identifier |
| Подпись | Keystore (debug/release) | Сертификат + профиль провижинга |
| Разрешения | Через манифест Android | Через Info.plist |
| Архитектуры | ARMv7, ARM64, x86 (по выбору) | ARM64 (обязательно для современных) |
| Ограничение размера | 100 МБ для APK, остальное в OBB | До 4 ГБ, но рекомендуется оптимизация |
| Тестирование | Любые устройства с отладкой | Зарегистрированные устройства + TestFlight |
| Распространение | Google Play, прямые ссылки | App Store, TestFlight, Enterprise |
Эти различия формируют два совершенно отдельных пайплайна внутри одного проекта FireMonkey, и синхронизировать их вручную становится сложно уже после нескольких релизов. Опытные разработчики автоматизируют оба процесса через скрипты MSBuild или сторонние инструменты CI/CD, что ускоряет выпуск обновлений и снижает влияние человеческого фактора. Самый ценный опыт приходит через реальные проекты, где каждый из описанных нюансов проявляется в конкретных условиях.