15502
Актуальное по мобильной разработке — Android, iOS, кроссплатформа Разместить рекламу: @tproger_sales_bot Правила общения: https://tprg.ru/rules Другие каналы: @tproger_channels Сайт: https://tprg.ru/site Другие наши проекты: https://tprg.ru/media
Почему 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 объединяли перед записью в хранилище, а форматирование перенесли с загрузки данных на чтение.