mobi_dev | Unsorted

Telegram-канал mobi_dev - Мобильная разработка

15502

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

Subscribe to a channel

Мобильная разработка

Почему SwiftUI не видит Map без второго import

В представлении есть import SwiftUI, но компилятор не находит Map. Тип действительно существует — просто одного импорта для него недостаточно.

В разборе cross-import overlays показано, что при совместном импорте SwiftUI и MapKit компилятор подключает дополнительный модуль _MapKit_SwiftUI. Именно там находится представление Map. Импортировать этот внутренний модуль вручную не нужно.

Так устроены и другие интеграции: для PhotosPicker нужен PhotosUI, для WebView — WebKit, для VideoPlayer — AVKit вместе со SwiftUI.

Если знакомого типа нет ни в области видимости, ни в автодополнении, проверьте пару фреймворков, которые он связывает. В SDK правила таких подключений можно найти в каталогах .swiftcrossimport и файлах .swiftoverlay.

Читать полностью…

Мобильная разработка

Android-приложение в окне: что проверить кроме ширины

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

В руководстве Google по адаптации для Googlebook предлагается строить раскладку по доступному пространству окна через window size classes. Список и детали могут стоять рядом в широком окне и переходить к последовательной навигации в узком.

Отдельно стоит проверить фокус и клавиатурную навигацию, правый клик, hover, drag and drop и независимые экземпляры приложения. Desktop-эмулятор в Android Studio Canary позволяет прогнать изменение размеров окна и работу мыши, трекпада и клавиатуры прямо на рабочей машине.

Читать полностью…

Мобильная разработка

Showboat и Rodney помогают показать работу ИИ-агента

Саймон Уиллисон собирает демонстрации кода с помощью двух своих инструментов. Showboat выполняет команды и записывает их вывод в документ. Rodney управляет Chrome из командной строки и делает скриншоты интерфейса.

uvx showboat --help

Эту команду автор предлагает дать агенту: в справке есть всё необходимое, чтобы тот создал документ с демонстрацией новой функции.

Уиллисон замечал и обход механизма: агент напрямую правит текст отчёта. Тогда записанный вывод может расходиться с реальным запуском. Содержимое демонстрации тоже требует проверки.

#ии #инструменты

Читать полностью…

Мобильная разработка

Тепловая карта из шестиугольников в Swift Charts

Тысячи точек на карте перекрывают друг друга. Если сгруппировать наблюдения по ячейкам и передать их количество цветом, распределение становится проще читать.

В примере Matthaus Woolard Swift Charts отображает землетрясения в Новой Зеландии. Ячейки заданы координатами q/r, а шестиугольники нарисованы через собственный ChartSymbolShape.

Есть полезная деталь: одинаковый размер символов ещё не гарантирует правильные пропорции. Автор настраивает perceptualUnitRect, чтобы соседние ячейки сходились. Затем меняет линейную цветовую шкалу на symmetricLog — слабые различия становятся заметнее, но равные шаги цвета уже не означают равные разницы значений.

Читать полностью…

Мобильная разработка

🧑‍💻 Какие навыки помогают вам в разработке в 2026 году?

Что вы чаще используете в работе? В каких задачах помогает ИИ, а где проще справиться самостоятельно?

Мы решили собрать портрет современного разработчика — и приглашаем вас поделиться своим опытом. Расскажите, какие навыки вам пригодились и как вы используете ИИ. Если обходите его стороной, нам тоже интересно узнать почему.

Опрос анонимный и займёт около 5 минут. Результаты опубликуем в общем большом исследовании.

👉 Пройти опрос

Читать полностью…

Мобильная разработка

Swift 6.4 позволяет дождаться очистки в defer

После отмены задачи приложению всё ещё может понадобиться завершить очистку: отправить накопленные метрики или закрыть ресурс. Асинхронная операция при этом сама может реагировать на отмену.

В Swift 6.4 можно вызывать async-функции внутри defer: выполнение дождётся их завершения перед выходом. Для участка, который нужно защитить от отмены родительской задачи, появился withTaskCancellationShield.

В примере команды Swift защищённый блок отправляет метрики и закрывает файловый дескриптор. Такой участок стоит оставлять небольшим: защищать конкретную завершающую операцию, чтобы после отмены пользовательской задачи приложение не продолжало лишнюю работу.

Читать полностью…

Мобильная разработка

Как собрать Swift-пакет через Gradle без CocoaPods

Kotlin/Native получает привязки к Apple-коду через cinterop, которому нужны C- или Objective-C-заголовки. У Swift-пакета таких заголовков изначально нет, а Gradle самостоятельно его не собирает.

В разборе SDK RevenueCat показана цепочка: SwiftPM описывает пакет, Gradle запускает сборку Swift, создаёт Objective-C-заголовок, статическую библиотеку и module map. Затем cinterop упаковывает привязки и библиотеку в klib.

Отдельная проблема — кеш. Изменение тела Swift-функции может не изменить заголовок, и cinterop пропустит обновление. RevenueCat добавляет хеш исходников в .def, чтобы изменения запускали задачу заново. У этого решения есть ограничения для зависимостей и конфигураций сборки.

Читать полностью…

Мобильная разработка

Почему KMP-код красный в IDE, но успешно собирается

Общий код KMP иногда видит платформенные объявления из зависимостей во время сборки, хотя IDE считает их недоступными. Из-за этого могут различаться выбранная перегрузка, выведенный тип и результат выполнения.

В Kotlin 2.5.0-Beta1 появилась экспериментальная отдельная компиляция. Она разрешает обращения из общих source sets по metadata KLIB, чтобы компилятор соблюдал те же границы, что и IDE.

Включается через kotlin.kmp.separateCompilation=true. Старые неявные обращения к платформенному коду могут перестать собираться: связь потребуется описать через expect/actual. Для проектов с C interop ещё остаются известные проблемы.

Читать полностью…

Мобильная разработка

SwiftFairy проверяет структуру SwiftUI-кода локально

Агент может знать правило и всё равно написать код, который ему противоречит. SwiftFairy разбирает Swift-код на Mac, ищет известные проблемные конструкции и через MCP возвращает замечания с привязкой к строкам и примерами исправлений.

Один из примеров — ForEach внутри List, где каждый элемент создаёт разное количество строк. Чтобы посчитать их, SwiftUI приходится вычислять содержимое для всех элементов коллекции, что замедляет длинный список.

Проверки сопоставляют структуру кода с заданными шаблонами. Сейчас есть наборы для SwiftUI, Swift Charts и современного Swift; найденное замечание стоит рассматривать вместе с контекстом конкретного экрана.

Читать полностью…

Мобильная разработка

Kotlin 2.4.20 упрощает передачу sealed-типов в Swift

В Kotlin 2.4.20 Swift Export получил поддержку sealed-классов и интерфейсов. Через sealedType() можно получить Swift enum и разобрать варианты в switch без default. Когда в Kotlin появится новый подкласс, компилятор поможет найти необработанную ветку.

Для XCFramework со SwiftPM-зависимостями задача assembleSharedXCFramework теперь генерирует Package.swift. Его нужно распространять вместе с фреймворком, чтобы зависимости корректно разрешались.

Инкрементальная компиляция klib перешла в Beta. Для проверки в своём проекте её включают через kotlin.incremental.native=true в gradle.properties; по умолчанию она пока не активирована.

Читать полностью…

Мобильная разработка

Как показать данные, пока остальные запросы ещё выполняются

Для одного экрана CardioBot нужно 40–50 запросов к HealthKit. Если собрать их результаты в один объект и только потом обновить интерфейс, пользователь будет ждать завершения всей загрузки.

В разборе Majid данные загружаются через AsyncSequence: каждый шаг возвращает накопленный снимок, а ViewModel обновляет состояние в цикле for await. Внутри отдельных шагов можно сохранить параллельные запросы через async let.

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

Читать полностью…

Мобильная разработка

SwiftUI List против UICollectionView: как измерить тяжёлую ленту в iOS 26.1

Автор собрал две версии одной ленты: с GIF-анимациями, изображениями высокого разрешения, градиентами, ячейками разного размера и жестами. Общую модель данных и обработку GIF он по возможности оставил одинаковыми, чтобы сравнение SwiftUI и UIKit не свелось к разнице в реализации.

В разборе профилирования List и UICollectionView показаны замеры задержек кадров, памяти, загрузки процессора и нагрева на iPhone 17 с iOS 26.1. Например, SwiftUI-версия за 24 секунды получила 78 задержек кадров и два зависания примерно по две секунды.

Это не универсальный приговор фреймворку, а воспроизводимый стенд с открытым проектом. Его можно взять за основу, чтобы прогнать собственный экран через Instruments и сравнить реализации на целевых устройствах перед выбором UI-фреймворка.

Читать полностью…

Мобильная разработка

Как нативные контролы SwiftUI меняются в iOS 26 без правок интерфейса

Один бинарник, собранный в Xcode 26.6 с SDK iOS 26.5 и минимальной версией iOS 17, запустили на iOS 17.5 и 26.3. Визуальное сравнение интерфейсов показывает изменения, которые SwiftUI применяет автоматически: добавлять glassEffect() не требуется.

Кнопки становятся капсульными, ползунки с шагом получают деления, панель вкладок приподнимается над контентом. У переключателей, сегментированного выбора, панелей инструментов и модальных экранов тоже меняются формы и фон.

После обновления SDK стоит пересобрать приложение и проверить основные экраны на старой и новой iOS. Сворачивание панели вкладок и собственные стеклянные эффекты уже требуют дополнительных API.

Читать полностью…

Мобильная разработка

Почему @ObservedObject сбрасывает модель в SwiftUI

@ObservedObject следит за изменениями модели, полученной извне, но не хранит созданный внутри представления экземпляр. Когда состояние родителя меняется, SwiftUI может заново создать значение дочернего View. Вместе с ним появится новый CounterViewModel, а счётчик вернётся к нулю.

Если дочернее представление само создаёт модель, объявляйте её через @StateObject. SwiftUI сохранит экземпляр, пока считает представление тем же самым. Если модель создаёт родитель, он хранит её через @StateObject и передаёт ребёнку как @ObservedObject.

Для нового кода под iOS 17 и новее источник предлагает @Observable с @State, но правило владения остаётся тем же. Пример со сбрасывающимся счётчиком и варианты исправления приведены с кодом.

Читать полностью…

Мобильная разработка

Как внедрить Maestro в React Native и не дублировать E2E-тесты

Команда Add Jam сравнила внедрение Maestro и Detox. Maestro работает вне кодовой базы приложения: достаточно установить консольную утилиту и направить её на запущенную сборку. Тесты описываются в YAML, а одни и те же сценарии и проверки запускаются на iOS и Android без изменений.

Повторяющиеся действия, например вход и переход к нужному экрану, авторы вынесли в переиспользуемые сценарии. В Detox им прежде требовались нативные зависимости, изменения конфигурации сборки и шаблонный код до первого теста.

Ограничения тоже разобраны: селекторы по testID нестабильно находили перекрывающиеся и абсолютно позиционированные элементы. Приходилось нажимать по координатам, из-за чего тест зависел от вёрстки. Ещё виртуальная клавиатура мешала следующим нажатиям, а LogBox перекрывал элементы интерфейса.

Читать полностью…

Мобильная разработка

Когда кнопки SwiftUI переезжают на край экрана

На iPhone Duo действия, навигация и вкладки могут оказаться в общей вертикальной панели. Для стандартных кнопок адаптация автоматическая, а пользовательским подписям и сложным контролам иногда нужна настройка.

В разборе Natalia Panferova показаны API iOS 27.1: axisBehavior задаёт предпочтительное размещение элемента, а toolbarVerticalEdge помогает перестроить его содержимое под выбранный край экрана.

При нехватке места toolbarVerticalCompressionBehavior позволяет выбрать приоритет: сохранить вкладки и убрать часть действий в overflow или оставить действия, свернув вкладки. Для конкретного окна или sheet вертикальную панель можно отключить через toolbarVerticalBehavior(.disabled).

Читать полностью…

Мобильная разработка

Почему LLDB показывает объект, но спотыкается о его свойство

На брейкпоинте p myObj работает, а p myObj.myComputedProperty требует больше времени или упирается в импорт модуля. Эти команды проходят разными путями: значение переменной можно прочитать по отладочной информации и reflection metadata, вычисляемое свойство требует выполнения кода.

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

Изменения в Swift 6.3–6.4 позволяют хранить точные пути к явно собранным модулям и их зависимостям. Xcode и SwiftPM передают нужные данные автоматически. Собственным системам сборки, которые напрямую вызывают Swift frontend, может понадобиться настройка debug-module-path.

Читать полностью…

Мобильная разработка

Как Instagram Direct переносил списки на Compose

В Direct сотни типов элементов списка. Переписать их и одновременно заменить RecyclerView — слишком много изменений для одного сравнения производительности.

В кейсе Google и Meta миграцию разделили: сначала переводили элементы на Compose небольшими группами, затем готовили переход на LazyColumn. Одни и те же компоненты работают в обоих контейнерах, а реализация переключается флагом для A/B-тестов.

Команда сравнивает время до первого взаимодействия, полной загрузки и плавность прокрутки на реальных пользователях. Небольшой Compose-компонент внутри старого экрана может давать искажённую картину из-за затрат на взаимодействие двух UI-систем. В статье также разобрано, как новая архитектура повлияла на работу ИИ-агентов с кодом.

Читать полностью…

Мобильная разработка

Экран погас, а приложение продолжает разряжать батарею

Загрузка завершилась с ошибкой, а CPU остался активным. Причиной может быть WakeLock: исключение, ранний return или потерянный callback не дали коду дойти до release(). На подключённом к зарядке телефоне такую утечку легко пропустить.

В разборе freeCodeCamp показаны типичные ошибки и способы их найти. Для ручной блокировки нужны таймаут и освобождение в finally, в том числе при отмене корутины. Самой операции тоже нужен срок выполнения.

Через adb shell dumpsys power можно увидеть текущие блокировки и время их удержания, через batterystats — накопленную статистику. Отложенную синхронизацию стоит сначала примерить к WorkManager: он управляет блокировкой за вас.

Читать полностью…

Мобильная разработка

KMP-плагин прекращает поддержку редактирования Swift

В новых версиях IntelliJ IDEA и Android Studio из KMP-плагина уберут редактирование Swift, подсветку синтаксиса и навигацию внутри Swift-файлов и между Swift и Kotlin. JetBrains объясняет решение снижением использования этих функций и стоимостью их сопровождения.

Изменение начинается с IntelliJ IDEA 2026.3 и Android Studio Rabbit 2 | 2026.2.2. Запуск iOS-приложений и отладка Kotlin-кода на iOS сохраняются. Swift Export и импорт Swift-пакетов также продолжают работать.

В прежних версиях IDE функции останутся без дальнейших обновлений. Командам со смешанным кодом стоит учесть это при обновлении IDE и перенести редактирование Swift в Xcode.

Читать полностью…

Мобильная разработка

В Kotlin появятся companion-блоки и расширения

Фабричный метод можно будет добавить типу, которым вы не управляете, даже если у него нет companion object. В новом механизме companion для этого предусмотрены companion extensions.

Companion-блоки на JVM компилируются в статические члены. Для KMP это также позволяет объявлять ожидаемые члены блока и предоставлять реализацию через статические члены Java-класса.

Функции экспериментальные и доступны с Kotlin 2.5.0-Beta1 через флаги компилятора. Companion extensions создают pre-release-бинарники с ограничениями для использования библиотек. Переписывать существующие companion object не требуется; они остаются нужны, например, когда объект реализует интерфейс.

Читать полностью…

Мобильная разработка

Как проверить SF Symbols до запуска приложения

Название иконки выглядит правдоподобно, но символа может не существовать или он появится только в новой iOS. В руководстве по CLI SF Symbols показано, как проверять это из терминала.

Команда search поддерживает точное совпадение имени, минимальную версию платформы и вывод JSON. Фильтр учитывает переименования: например, для iOS 13 вместо xmark.bin нужен bin.xmark.

Версии доступности различаются и по режимам рендеринга. heart.fill есть в iOS 13, а multicolor для него требует iOS 15. Проверку имени и нужного режима можно добавить в инструкции агенту, чтобы он сверял каталог перед созданием Image(systemName:).

Читать полностью…

Мобильная разработка

От чатбота к агентам: опыт Митчелла Хашимото

Для работы с кодом Хашимото перешёл от отдельного чата к агенту, который читает файлы проекта и запускает программы. После этого начал повторять собственную работу: сначала решал задачу сам, затем давал её агенту без готового решения.

Так он выяснял, какие задачи можно поручать ИИ. Дальше добавлял инструкции в AGENTS.md, файл с правилами проекта, и способы проверить изменения, включая запуск тестов.

В истории освоения ИИ в разработке Хашимото связывает выбор задач с настройкой рабочего окружения. Отдельные чаты при этом остались в его повседневной работе.

#ии #инструменты

Читать полностью…

Мобильная разработка

В Xcode появился JSON-формат проекта

Добавление файла в старый project.pbxproj меняет несколько секций и создаёт новые идентификаторы. Когда два разработчика делают это в разных ветках, приходится разбирать конфликты в описании проекта.

В разборе нового формата Xcode 27.2 показан project.xcproj: файл описывается одной записью, а настройки сборки не приходится дублировать для каждой конфигурации. В примере автора 300 строк property list превратились в 123 строки JSON.

Переключение доступно в File inspector проекта. Перед миграцией нужно проверить версии Xcode в команде и инструменты, которые читают project.pbxproj напрямую: CocoaPods, XcodeGen, Tuist и собственные CI-скрипты.

Читать полностью…

Мобильная разработка

Что меняется в подписках Google Play

Подписка и разовая покупка обычно требуют отдельных оплат. В обзоре новых возможностей Google Play описан Mixed Carts: подписку с автопродлением и разовый товар можно оформить через один вызов API и общий экран оплаты.

Среди других направлений — покупка нескольких мест для команды и предоплаченный баланс с автоматическим пополнением для функций с переменной стоимостью. Часть возможностей проходит тестирование с партнёрами или распространяется через Early Access.

In-App Messaging API уже доступен всем разработчикам. Он позволяет прямо в приложении предложить исправить отклонённый платёж или сообщить о предстоящем изменении цены.

Читать полностью…

Мобильная разработка

Пять функций Android Studio для работы с изменениями в коде

Android Studio умеет отложить локальные правки без коммита, упаковать их в патч и разобрать конфликт слияния в редакторе из трёх секций. Это пригодится Android-разработчику при переключении между задачами и ревью кода.

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

Отложенные правки хранит сама IDE, а не Git. Если установка Android Studio повредится, изменения можно потерять. В материале показаны действия в меню и снимки интерфейса.

Читать полностью…

Мобильная разработка

Как закрепить границы Clean Architecture в Swift Packages

Папки Domain, Data и Presentation сами по себе не мешают экрану обратиться к базе или стороннему SDK. В разборе SwiftUI-приложения Popcorn каждую архитектурную границу превращают в отдельный Swift Package с явным списком зависимостей.

Контексты отвечают за предметные области вроде фильмов и поиска, а feature-модули содержат экраны и модели представления. Внутри контекста домен не зависит ни от чего, прикладной слой хранит сценарии, инфраструктура работает с источниками данных, а композиционный модуль связывает части. SDK TMDb остаётся в адаптере, поэтому остальной код о нём не знает.

Такие границы проверяет компилятор: запрещённый импорт ломает сборку, а добавление зависимости в Package.swift видно на ревью. Сценарии можно тестировать с поддельным репозиторием, без сети, базы и симулятора.

Читать полностью…

Мобильная разработка

Как собрать стабильную пирамиду тестов для Flutter-приложения

Руководство по тестированию Flutter разбирает unit-, widget-, golden- и integration-тесты. Логику предлагают выносить из виджетов, связи интерфейса проверять widget-тестами, а запуск, авторизацию, покупки, плагины и платформенные каналы — на устройстве или эмуляторе.

pumpAndSettle() ждёт прекращения новых кадров, поэтому бесконечный индикатор приводит к тайм-ауту. Вместо него автор управляет кадрами через pump(), а асинхронным результатом — через Completer.

Для golden-тестов разобраны расхождения снимков в macOS и Linux CI: влияют шрифты и окружение. Их лучше оставить для выбранных компонентов и запускать в зафиксированной среде.

Читать полностью…

Мобильная разработка

Как отделить эффект Baseline Profiles от очистки запуска Android-приложения

В Compose-приложении автора Baseline Profiles ускоряли запуск, но итоговые 18–34% появились после очистки стартового пути. Разбор эксперимента с запуском показывает, как не приписать весь результат профилю.

Автор сравнивал запуск без профиля в verify и с ним в speed-profile, каждый раз принудительно останавливая приложение. Затем убрал запуск интерфейса из фонового события, вынес чтение настроек и блокирующий ввод-вывод из критического пути.

Кейс пригодится для воспроизводимых замеров старта Android-приложения: цифра ускорения важна вместе с её причиной.

Читать полностью…

Мобильная разработка

Как ускорить React Native-приложение с картой и Zustand

На слабых Android-устройствах карта с сотнями маркеров тормозила, а экраны перерисовывались чаще нужного. Разбор оптимизации рабочего проекта показывает, где команда искала причины.

Компоненты вынесли из родительского: иначе React заново монтирует их из-за новой ссылки на функцию. В Zustand компоненты подписали отдельными селекторами только на нужные данные.

Маркеры обновляли лишь при изменении счётчика, поиск по массиву заменили заранее собранной Map. Страницы API объединяли перед записью в хранилище, а форматирование перенесли с загрузки данных на чтение.

Читать полностью…
Subscribe to a channel