Мобильная разработка
13.2K subscribers
961 photos
237 videos
3.08K links
Актуальное по мобильной разработке — Android, iOS, кроссплатформа

Разместить рекламу: @tproger_sales_bot
Правила общения: https://tprg.ru/rules
Другие каналы: @tproger_channels
Сайт: https://tprg.ru/site

Регистрация в перечне РКН: https://tprg.ru/oVBP
Download Telegram
Как ProfilingManager на Android 15+ помогает искать причины тормозов в продакшене

ProfilingManager собирает на устройствах трассировки процессора, образцы стека вызовов и дампы памяти. Datadog встроила API в мониторинг реальных пользователей: теперь команда видит не только долгий запуск или зависание главного потока, но и код с событиями системы, которые привели к проблеме.

Показательный случай: трассировка раскрыла, что фоновый сервис синтеза речи заранее запускался вместе с приложением, занимал самое производительное ядро процессора и заставлял главный поток ждать.

В разборе Android Developers' Blog описаны сбор миллионов профилей в неделю, встроенное ограничение частоты запросов и анализ трассировок через Perfetto. API доступен с Android 15, поэтому на более старых устройствах текущие средства телеметрии всё ещё нужны.
🎉1
Как вынести вычисления из ИИ-агента в Dart-код Flutter-приложения

В Flutter с GenUI агент может собирать экраны во время работы приложения. Но арифметику лучше не передавать ему: это тратит токены, требует ответа по сети и делает результат менее предсказуемым.

Клиентские функции A2UI позволяют зарегистрировать Dart-функцию, её параметры и тип результата. Агент вызывает её из сообщения, а приложение выполняет код на устройстве.

Так вычисления и форматирование валюты остаются в Dart-коде. В материале Flutter показаны реализация функции и её регистрация в каталоге GenUI.
🤝3🥱1
Как SwiftUI Agent Skill помогает улучшать код представлений

Открытый SwiftUI Agent Skill добавляет ИИ-агенту правила для SwiftUI. Компактный SKILL.md направляет его к отдельным справочникам по управлению состоянием, производительности, доступности и API, поэтому в контекст попадают только материалы под текущую задачу.

При ревью навык нашёл вложенные ScrollView и повторную синхронизацию состояния в onAppear и onChange. Версия 5.0.0 также содержит проверенные по интерфейсам SDK 27 рекомендации для Xcode 27, включая адаптивную вёрстку без привязки к фиксированному размеру экрана.

В материале SwiftLee есть установка через свежую версию skills CLI, обновление старой установки и пример запроса для ревью. Навык можно использовать для проверки сгенерированных SwiftUI-представлений и новых экранов.
🔥3🎉2
Как убрать задержку генеративного интерфейса во Flutter

В A2UI модель присылает JSON-сообщения с описанием компонентов, а пакет genui отрисовывает их во Flutter-приложении. Запрос к модели при каждом старте задерживает первый экран: ей нужно обработать инструкции, получить данные и собрать интерфейс.

Решение автора: при изменении записи серверная функция просит Gemini заранее создать A2UI-сообщение и сохраняет его в Firestore. Приложение при открытии читает готовый JSON и передаёт его в историю диалога и транспорт genui, обходя новый вызов модели.

У примера есть ограничение: триггеры Firestore в Dart пока экспериментальны и поддерживаются только в Firebase Emulator Suite. Серверный и клиентский код показан в разборе в блоге Flutter.
👌1
Room 3.0 переводит Android-разработчиков на Kotlin и KSP

В анонсе Room 3.0 команда отказалась от генерации Java-кода, Java Annotation Processing и KAPT. Новая версия генерирует только Kotlin-код и обрабатывает его через KSP, Kotlin Symbol Processing.

Room также больше не поддерживает API SupportSQLite: библиотека полностью переходит на драйверы androidx.sqlite, совместимые с Kotlin Multiplatform. Асинхронные API теперь строятся вокруг корутин Kotlin, в том числе ради поддержки веб-платформ.

Перед переходом на Room 3.0 проверьте сборку Android-приложения: модули с Java AP или KAPT придётся перевести на KSP, а код, завязанный на SupportSQLite, адаптировать к драйверам androidx.sqlite.
👍6🎉1
Как заставить Swift напомнить об удалении временного API

При поддержке iOS 18 и iOS 26 разработчику может понадобиться обёртка для различий между версиями. В примере из статьи ToolbarLabelStyle показывает текстовые кнопки на iOS 18 и значки на iOS 26. После повышения минимальной версии приложения до iOS 26 такой код станет лишним.

Аннотация @available превращает будущую уборку в проверку компилятора. Параметр deprecated: 26 помечает обращения предупреждением, когда минимальный таргет поднимется до iOS 26, а obsoleted: 27 сделает их ошибками на iOS 27. Можно сразу указать obsoleted: 26, но автор советует сначала объявить API устаревшим, затем запретить его.

В статье Swift with Majid показан полный пример обёртки и аннотации для её планового удаления.
👍1
Как загружать ресурсы iOS по требованию и не хранить токены в бинарнике

On-Demand Resources выносят изображения, модели и конфигурации из начальной загрузки: iOS скачивает их из App Store, кэширует и удаляет при нехватке места.

Механизм можно применить к API-токенам: загрузить конфигурацию по тегу и сохранить данные в Keychain. Но это не граница безопасности: после загрузки файлы доступны при доступе к устройству.

В статье Swift with Majid есть обёртка на Swift и пример загрузки конфигурации. Для нового кода Apple рекомендует вместо устаревших On-Demand Resources использовать Background Assets.
❤5
Как собрали ИИ-кофейню на Flutter и Firebase

GenLatte поддерживает iOS и Android, хотя посетители работали только с веб-версией. В одном монорепозитории команда объединила Flutter-приложение, серверную часть на Firebase и общий код: так бизнес-логика не расходилась между пятью интерфейсами для заказа, бариста, модерации и очереди.

Для персонализации Gemini превращал короткое описание «счастливого места» в четыре запроса к генератору изображений. Затем генеративный интерфейс выбирал подходящий элемент из небольшого набора фирменных виджетов: текстовое поле для открытого вопроса или переключатель для нескольких вариантов.

Из разбора команды Flutter можно забрать архитектуру общего приложения и централизованные проверки ролей через GoRouter и Firebase. Выпуск в App Store и Google Play, версии SDK и совместимость со старыми устройствами материал не рассматривает.
❤2🎉1
Как подготовить Android-интерфейс к широким складным экранам Samsung

Galaxy Z Fold8 получил сверхширокий основной экран с альбомной ориентацией. Android-разработчикам советуют отказаться от жёстких размеров и ориентации: выбирать компоновку по классу ширины окна, затем учитывать высоту.

Для Compose предлагают Grid, FlexBox и MediaQuery. Сгибы и шарниры лучше использовать как разделители, а состояние при складывании сохранять через ViewModel. Примеры собраны в статье Android Developers Blog.
🔥1😐1
Как заменить List собственным контейнером в SwiftUI

Для больших однородных наборов данных подходит List. Если экран iOS-приложения состоит из карточек разных типов, автор предлагает связку ScrollView и ленивого стека: она даёт точнее управлять оформлением и не требует модификаторов, работающих только внутри List.

Контейнер ScrollingSurface выбирает вертикальный или горизонтальный стек. DividedCard получает дочерние представления через Container View API и добавляет между ними разделители, а SectionedSurface извлекает секции и пропускает пустые. Отдельный стиль кнопки возвращает стрелку для навигации.

В статье «Building List replacement in SwiftUI» есть код всех компонентов и пример их сборки в экране приложения. Подход пригодится, когда стандартный список ограничивает дизайн, а данные не требуют переиспользования огромного числа одинаковых ячеек.
🎉1
Как довести код ИИ-агента в iOS до TestFlight

Donny Wals разбирает пайплайн, в котором агент пишет код, а разработчик сохраняет контроль над архитектурой и релизом. Правила для Swift, SwiftUI и тестов лежат в agents.md; агент Xcode 26.3 тоже читает этот файл.

Перед реализацией агент составляет план с перечнем файлов и выбранным подходом. После проверки плана он создаёт pull request, а Cursor BugBot ищет логические ошибки, крайние случаи и случайные изменения.

Bitrise запускает тесты для каждого pull request. После слияния в основную ветку второй сценарий ещё раз проверяет код, подписывает архив и загружает сборку в App Store Connect, откуда она попадает в TestFlight. Получается воспроизводимый путь до тестовой сборки без ручного запуска Xcode, но с проверкой плана, кода и тестов человеком.
🤝1
Как собирать диагностику iOS-приложения через MetricKit

Xcode Organizer показывает сбои, зависания, время запуска, расход памяти и завершения приложения, но не всегда объясняет причину завершения. MetricKit отдаёт системные метрики и диагностику, которые можно отправить в свою аналитику.

В примере на Swift AppDelegate подписывается на MXMetricManager. Один обработчик получает MXMetricPayload со счётчиками фоновых завершений из-за лимитов CPU и памяти, другой получает MXDiagnosticPayload с данными о сбоях.

Система может агрегировать отчёты и доставлять их раз в сутки или чаще, поэтому на точное расписание рассчитывать нельзя. timeStampBegin и timeStampEnd показывают период данных, а JSON-представление можно выгрузить в собственный API и обработать на бэкенде.
👍1🤝1
Как изолировать ViewModel по записи навигации в Android Navigation 3

После миграции с Navigation 2 вызов viewModel() может сохранять состояние экрана: в Compose-приложении с одной Activity модель по умолчанию привязана к Activity.

Для отдельной ViewModel у каждой записи добавьте lifecycle-viewmodel-navigation3:2.10.0 и передайте в NavDisplay декораторы rememberSaveableStateHolderNavEntryDecorator() и rememberViewModelStoreNavEntryDecorator(). Новая запись получит свой экземпляр, а удаление из стека очистит его.

Готовая конфигурация NavDisplay поможет выбрать между свежим состоянием экрана и общей моделью.
🤝1