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

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

Регистрация в перечне РКН: https://tprg.ru/oVBP
Download Telegram
Как заставить 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» есть код всех компонентов и пример их сборки в экране приложения. Подход пригодится, когда стандартный список ограничивает дизайн, а данные не требуют переиспользования огромного числа одинаковых ячеек.
🎉2
Как довести код ИИ-агента в 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 и обработать на бэкенде.
🤝2👍1
Как изолировать ViewModel по записи навигации в Android Navigation 3

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

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

Готовая конфигурация NavDisplay поможет выбрать между свежим состоянием экрана и общей моделью.
🤝3
Как передать изображение в Foundation Models и получить Swift-структуру

Мультимодальный ввод позволяет отдать модели фотографию прямо из iOS-приложения. В примере снимок блюда превращается в PlateClassification: структура с названием блюда и признаками сахара, белка, клетчатки и насыщенных жиров.

Схема такая: @Generable задаёт тип результата, PromptBuilder объединяет инструкцию с Attachment, а LanguageModelSession возвращает заполненную структуру через result.content. Вложение можно создать из URL, буфера пикселей, CGImage или CIImage.

Практический разбор с кодом показывает весь путь от изображения до данных для интерфейса. Требования к версии iOS и совместимым устройствам автор не приводит, поэтому перед внедрением их стоит сверить с документацией SDK.
❤1👍1
Как обновлять схемы SwiftData и не ломать данные после релиза

После обновления iOS-приложение открывает существующее хранилище. Поэтому даже первую модель автор советует выпускать через VersionedSchema: она станет исходной точкой для следующих версий.

SwiftData сама переносит данные при лёгких изменениях, например при добавлении необязательного свойства. Новое обязательное поле без значения, смена типа или объединение сущностей требуют ручного преобразования через SchemaMigrationPlan и MigrationStage.

Разбор миграций SwiftData объясняет, как учитывать пользователей, которые пропускают версии приложения, и когда нужны промежуточные схемы. Проверяйте переход с реального хранилища на диске: значение по умолчанию в Swift-инициализаторе не гарантирует заполнение старых записей.
👍1
Как добавить свайп-действия в Android без устаревшего API

В Compose Material 3 компонент SwipeToDismissBox позволяет назначить разные действия для свайпов влево и вправо. В примере элемент списка после одного жеста помечается прочитанным, после другого удаляется.

Состояние создаётся через rememberSwipeToDismissBoxState без устаревшего confirmValueChange. Направление жеста обрабатывается в колбэке компонента, а reset() возвращает элемент на место перед отметкой прочитанного. Фон меняет цвет и значок в зависимости от направления и хода свайпа. Для элементов списка используются стабильные ключи, чтобы состояние не переезжало между строками.

Пошаговый пример с кодом рассчитан на Material 3 1.4.0 и 1.5.0-alpha11. Если в проекте другая версия библиотеки, перед внедрением сверьте сигнатуры API.
🔥1💯1
Как показывать ответ Foundation Models в iOS по мере генерации

В Swift метод respond возвращает результат после завершения генерации. Для постепенного обновления интерфейса можно вызвать streamResponse: он создаёт ResponseStream, который перебирается через for try await и выдаёт частичные версии объекта.

Макрос @Generable добавляет тип PartiallyGenerated с необязательными свойствами. Модель заполняет поля в порядке объявления, поэтому заголовок, текст и подсказки стоит выводить в той же последовательности.

Разбор потоковой генерации также показывает collect(): после перебора потока метод возвращает итоговый структурированный объект.
❤1