Обеспечение совместимости мобильного приложения с новыми устройствами
Apple выпустила iPhone 16 с новым формфактором и Dynamic Island вместо notch. Через неделю пользователи начали слать скриншоты: статус-бар перекрывает контент, кнопки ушли под Home Indicator, камера закрывает часть интерфейса. Приложение не сломалось — оно просто не знало о новых Safe Area insets.
Что конкретно ломается при выходе нового устройства
Safe Area и Dynamic Island. На iOS Safe Area insets зависят от модели устройства. Hardcoded отступы — UIEdgeInsets(top: 44, left: 0, bottom: 34, right: 0) — неверны уже для трёх поколений iPhone. Правильно: view.safeAreaInsets или safeAreaLayoutGuide в Auto Layout. В SwiftUI — .ignoresSafeArea() с явным указанием краёв, не глобально.
Display cutout на Android. С Android 9 появился DisplayCutout API. Устройства с вырезом под камеру (Pixel, Samsung A-серия, Xiaomi) имеют WindowInsets.getDisplayCutout(). Если приложение не учитывает LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES или NEVER, контент уходит под вырез на полноэкранных фрагментах.
Изменение aspect ratio. Флагманы 2023–2024 имеют ratio 19.5:9 и 20:9. Если layoutы сверстаны под 16:9 с фиксированными высотами — контент или растянется, или появятся чёрные полосы. На Android тест через <activity android:maxAspectRatio> — если не указан, ОС может ограничить приложение letterbox режимом.
Foldable и большие экраны. Samsung Fold, Pixel Fold — приложение получает configuration change при разворачивании. Если Activity не обрабатывает configChanges="screenSize|smallestScreenSize|screenLayout|orientation", происходит пересоздание с потерей состояния. Jetpack WindowManager FoldingFeature позволяет адаптировать layout под состояние петли.
Процесс проверки совместимости
Новое устройство тестируем по слоям:
-
Симулятор/эмулятор — первичная проверка layout на новом формфакторе без реального устройства. Xcode Simulator для iPhone 16 Pro появляется с релизом Xcode. Android Emulator — создаём AVD с нужным разрешением и плотностью.
-
Firebase Test Lab / BrowserStack — прогон UI-тестов на реальном парке устройств. Особенно важно для Android: фрагментация огромна, эмулятор не воспроизводит специфичные баги кастомных launcher'ов и оболочек.
-
Реальное устройство — для touch, Face ID, камеры, NFC. Некоторые баги воспроизводятся только на железе.
Для iOS: проверяем traitCollection.horizontalSizeClass и verticalSizeClass, UIScreen.main.bounds (хотя для layout лучше не полагаться на глобальный bounds — используем container-relative layout).
Для Android: WindowMetricsCalculator.computeCurrentWindowMetrics(activity) из Jetpack WindowManager вместо устаревшего Display.getSize().
Типичные находки при аудите
- ScrollView без
contentInsetAdjustmentBehavior = .automatic— контент уходит под Navigation Bar -
WebViewс фиксированной высотой вместо constraint кsafeAreaLayoutGuide.bottomAnchor - Splash screen с hardcoded размером — не масштабируется на Pro Max / Ultra
-
getStatusBarHeight()через reflection в старом Android-коде — возвращает 0 на некоторых новых устройствах
Сроки
Аудит совместимости с новыми устройствами и правка критичных багов — 2–3 дня. Если приложение изначально писалось без Auto Layout / ConstraintLayout (старый frame-based код) — может потребоваться значительный рефакторинг.







