Как изолировать ViewModel по записи навигации в Android Navigation 3
После миграции с Navigation 2 вызов
Для отдельной ViewModel у каждой записи добавьте
Готовая конфигурация NavDisplay поможет выбрать между свежим состоянием экрана и общей моделью.
После миграции с Navigation 2 вызов
viewModel() может сохранять состояние экрана: в Compose-приложении с одной Activity модель по умолчанию привязана к Activity.Для отдельной ViewModel у каждой записи добавьте
lifecycle-viewmodel-navigation3:2.10.0 и передайте в NavDisplay декораторы rememberSaveableStateHolderNavEntryDecorator() и rememberViewModelStoreNavEntryDecorator(). Новая запись получит свой экземпляр, а удаление из стека очистит его.Готовая конфигурация NavDisplay поможет выбрать между свежим состоянием экрана и общей моделью.
🤝3
Как передать изображение в Foundation Models и получить Swift-структуру
Мультимодальный ввод позволяет отдать модели фотографию прямо из iOS-приложения. В примере снимок блюда превращается в
Схема такая:
Практический разбор с кодом показывает весь путь от изображения до данных для интерфейса. Требования к версии iOS и совместимым устройствам автор не приводит, поэтому перед внедрением их стоит сверить с документацией SDK.
Мультимодальный ввод позволяет отдать модели фотографию прямо из iOS-приложения. В примере снимок блюда превращается в
PlateClassification: структура с названием блюда и признаками сахара, белка, клетчатки и насыщенных жиров.Схема такая:
@Generable задаёт тип результата, PromptBuilder объединяет инструкцию с Attachment, а LanguageModelSession возвращает заполненную структуру через result.content. Вложение можно создать из URL, буфера пикселей, CGImage или CIImage.Практический разбор с кодом показывает весь путь от изображения до данных для интерфейса. Требования к версии iOS и совместимым устройствам автор не приводит, поэтому перед внедрением их стоит сверить с документацией SDK.
❤1👍1
Как обновлять схемы SwiftData и не ломать данные после релиза
После обновления iOS-приложение открывает существующее хранилище. Поэтому даже первую модель автор советует выпускать через
SwiftData сама переносит данные при лёгких изменениях, например при добавлении необязательного свойства. Новое обязательное поле без значения, смена типа или объединение сущностей требуют ручного преобразования через
Разбор миграций SwiftData объясняет, как учитывать пользователей, которые пропускают версии приложения, и когда нужны промежуточные схемы. Проверяйте переход с реального хранилища на диске: значение по умолчанию в Swift-инициализаторе не гарантирует заполнение старых записей.
После обновления iOS-приложение открывает существующее хранилище. Поэтому даже первую модель автор советует выпускать через
VersionedSchema: она станет исходной точкой для следующих версий.SwiftData сама переносит данные при лёгких изменениях, например при добавлении необязательного свойства. Новое обязательное поле без значения, смена типа или объединение сущностей требуют ручного преобразования через
SchemaMigrationPlan и MigrationStage.Разбор миграций SwiftData объясняет, как учитывать пользователей, которые пропускают версии приложения, и когда нужны промежуточные схемы. Проверяйте переход с реального хранилища на диске: значение по умолчанию в Swift-инициализаторе не гарантирует заполнение старых записей.
👍1
Как добавить свайп-действия в Android без устаревшего API
В Compose Material 3 компонент
Состояние создаётся через
Пошаговый пример с кодом рассчитан на Material 3 1.4.0 и 1.5.0-alpha11. Если в проекте другая версия библиотеки, перед внедрением сверьте сигнатуры API.
В Compose Material 3 компонент
SwipeToDismissBox позволяет назначить разные действия для свайпов влево и вправо. В примере элемент списка после одного жеста помечается прочитанным, после другого удаляется.Состояние создаётся через
rememberSwipeToDismissBoxState без устаревшего confirmValueChange. Направление жеста обрабатывается в колбэке компонента, а reset() возвращает элемент на место перед отметкой прочитанного. Фон меняет цвет и значок в зависимости от направления и хода свайпа. Для элементов списка используются стабильные ключи, чтобы состояние не переезжало между строками.Пошаговый пример с кодом рассчитан на Material 3 1.4.0 и 1.5.0-alpha11. Если в проекте другая версия библиотеки, перед внедрением сверьте сигнатуры API.
🔥1💯1
Как показывать ответ Foundation Models в iOS по мере генерации
В Swift метод
Макрос
Разбор потоковой генерации также показывает
В Swift метод
respond возвращает результат после завершения генерации. Для постепенного обновления интерфейса можно вызвать streamResponse: он создаёт ResponseStream, который перебирается через for try await и выдаёт частичные версии объекта.Макрос
@Generable добавляет тип PartiallyGenerated с необязательными свойствами. Модель заполняет поля в порядке объявления, поэтому заголовок, текст и подсказки стоит выводить в той же последовательности.Разбор потоковой генерации также показывает
collect(): после перебора потока метод возвращает итоговый структурированный объект.❤1
Как перевести платное iOS-приложение на freemium и сохранить доступ покупателям
Схема миграции через StoreKit опирается на
В TestFlight и среде ревью исходная версия всегда «1.0», а в production приходит номер сборки: сравнивайте номера сборок. Для отладки добавьте ручное переключение статуса, иначе ревьюер не увидит покупку.
После переустановки исходная версия меняется на текущую. Для одного устройства статус храните в Keychain, для нескольких понадобится CloudKit или сервер.
Схема миграции через StoreKit опирается на
AppTransaction: исходная версия и дата покупки помогают распознать тех, кто установил приложение до перехода. Им можно выдать пожизненный доступ.В TestFlight и среде ревью исходная версия всегда «1.0», а в production приходит номер сборки: сравнивайте номера сборок. Для отладки добавьте ручное переключение статуса, иначе ревьюер не увидит покупку.
После переустановки исходная версия меняется на текущую. Для одного устройства статус храните в Keychain, для нескольких понадобится CloudKit или сервер.
👍1
Как Baseline Profiles ускоряют запуск и прокрутку Android-приложений
ART сначала интерпретирует байткод Kotlin и Java, а затем компилирует часто вызываемые методы. Baseline Profile заранее задаёт нужные классы и методы: с Android 9 ART компилирует их при установке приложения.
Meta собирает последовательности загрузки классов для запуска, прокрутки ленты и открытия фото. По данным компании, профили улучшили отдельные ключевые метрики до 40%.
Опыт Meta с Baseline Profiles показывает, как ускорять не только холодный запуск.
ART сначала интерпретирует байткод Kotlin и Java, а затем компилирует часто вызываемые методы. Baseline Profile заранее задаёт нужные классы и методы: с Android 9 ART компилирует их при установке приложения.
Meta собирает последовательности загрузки классов для запуска, прокрутки ленты и открытия фото. По данным компании, профили улучшили отдельные ключевые метрики до 40%.
Опыт Meta с Baseline Profiles показывает, как ускорять не только холодный запуск.
👍2🎉2
Как собрать фильтры и индикаторы в Android на Compose Material 3
В Compose Material 3 есть готовые компоненты для интерфейсов, которые часто собирают вручную.
Для фильтра по цене подойдёт
Примеры компонентов с кодом подходят для Material 3 версий 1.3.2, 1.4.0-beta02 и 1.5.0-alpha04: используемый API между ними не менялся.
В Compose Material 3 есть готовые компоненты для интерфейсов, которые часто собирают вручную.
TriStateCheckbox связывает общий флажок с дочерними: показывает, выбраны все пункты, ни одного или только часть. SegmentedButton позволяет выбрать один или несколько вариантов из двух-пяти.Для фильтра по цене подойдёт
RangeSlider, а BadgedBox поможет оформить индикатор непрочитанных уведомлений. При переносе примера с ползунком проверьте начальную границу диапазона: её нужно исправить. Параметр steps задаёт количество промежуточных значений, а не общее число позиций.Примеры компонентов с кодом подходят для Material 3 версий 1.3.2, 1.4.0-beta02 и 1.5.0-alpha04: используемый API между ними не менялся.
Как передавать контент между iOS-приложениями через Siri
Чтобы Siri могла отдать сущность другому приложению, AppEntity представляют системным типом. В примере ContactEntity содержит IntentPerson, реализует Transferable и передаёт свойство через IntentValueRepresentation. Так система получает значение для обмена.
При импорте IntentValueQuery ищет сохранённый контакт по имени, телефону, адресу почты или ID. Пустой результат запускает importing-замыкание: оно создаёт новую сущность и сохраняет контакт. Правила сопоставления остаются в приложении.
Разбор передачи контента через App Intents содержит Swift-код обоих направлений. Минимальная версия iOS и требования SDK не указаны, поэтому совместимость нужно отдельно сверить с документацией Apple.
Чтобы Siri могла отдать сущность другому приложению, AppEntity представляют системным типом. В примере ContactEntity содержит IntentPerson, реализует Transferable и передаёт свойство через IntentValueRepresentation. Так система получает значение для обмена.
При импорте IntentValueQuery ищет сохранённый контакт по имени, телефону, адресу почты или ID. Пустой результат запускает importing-замыкание: оно создаёт новую сущность и сохраняет контакт. Правила сопоставления остаются в приложении.
Разбор передачи контента через App Intents содержит Swift-код обоих направлений. Минимальная версия iOS и требования SDK не указаны, поэтому совместимость нужно отдельно сверить с документацией Apple.
❤1👍1
Как встроить генерацию изображений через Image Playground в iOS-приложение
Фреймворк Image Playground позволяет создавать изображения в Swift из текста, фотографии, рисунка PencilKit или большого текстового фрагмента. За генерацию отвечает
Доступны стили animation, illustration и sketch, но конкретный набор зависит от устройства. Перед вызовом стоит проверить
Примеры на Swift показывают, как передать текст вместе с исходной картинкой и получить
Фреймворк Image Playground позволяет создавать изображения в Swift из текста, фотографии, рисунка PencilKit или большого текстового фрагмента. За генерацию отвечает
ImageCreator: метод images получает описание, стиль и число результатов, а затем возвращает их по одному через AsyncSequence.Доступны стили animation, illustration и sketch, но конкретный набор зависит от устройства. Перед вызовом стоит проверить
availableStyles; создание ImageCreator может завершиться ошибкой, если устройство не поддерживает генерацию. За один запрос система выдаёт не больше четырёх изображений.Примеры на Swift показывают, как передать текст вместе с исходной картинкой и получить
CGImage. Минимальную версию ОС и список совместимых устройств статья не называет, поэтому их нужно проверить отдельно перед внедрением.Как загружать локальный HTML в SwiftUI WebView через свою URL-схему
В iOS 26 у SwiftUI появились WebView и WebPage, а собственная URL-схема позволяет загружать локальные ресурсы. Например, приложение может открыть
Обработчик URLSchemeHandler получает запрос, проверяет схему, находит файл, определяет MIME-тип и читает данные. Затем он последовательно передаёт в асинхронный поток URLResponse и содержимое файла, а при ошибке завершает поток с исключением.
Обработчик регистрируется в WebPage.Configuration, созданная WebPage передаётся в WebView, а загрузка запускается через
В iOS 26 у SwiftUI появились WebView и WebPage, а собственная URL-схема позволяет загружать локальные ресурсы. Например, приложение может открыть
quotes://001.html, найти файл в основном пакете и показать страницу без сервера.Обработчик URLSchemeHandler получает запрос, проверяет схему, находит файл, определяет MIME-тип и читает данные. Затем он последовательно передаёт в асинхронный поток URLResponse и содержимое файла, а при ошибке завершает поток с исключением.
Обработчик регистрируется в WebPage.Configuration, созданная WebPage передаётся в WebView, а загрузка запускается через
page.load. Метод возвращает события, по которым можно отслеживать ход загрузки. Перед внедрением проверьте минимальную версию приложения: этот API доступен начиная с iOS 26.Как ускорить первый кадр камеры в iOS 26 с AVFoundation
Apple предлагает разделить запуск камеры: сначала создать превью и кнопку затвора, а остальные элементы интерфейса и выходы захвата инициализировать позже. В докладе о быстром запуске камеры Deferred Start сократил ожидание превью примерно вдвое.
AVCaptureSession, startRunning и stopRunning блокируют поток, поэтому их не стоит вызывать в главном потоке. Конфигурацию применяют один раз, а при Deferred Start откладывают все выходы, кроме превью.
API доступен с iOS 26. При сборке с SDK iOS 26 автоматический режим включён по умолчанию. Первый кадр появится раньше, но фотосъёмка не ускорится, пока не готов её выход.
Apple предлагает разделить запуск камеры: сначала создать превью и кнопку затвора, а остальные элементы интерфейса и выходы захвата инициализировать позже. В докладе о быстром запуске камеры Deferred Start сократил ожидание превью примерно вдвое.
AVCaptureSession, startRunning и stopRunning блокируют поток, поэтому их не стоит вызывать в главном потоке. Конфигурацию применяют один раз, а при Deferred Start откладывают все выходы, кроме превью.
API доступен с iOS 26. При сборке с SDK iOS 26 автоматический режим включён по умолчанию. Первый кадр появится раньше, но фотосъёмка не ускорится, пока не готов её выход.