Сначала зафиксируйте Flutter на версии с поддержкой пути DeviceHub.app, затем проверьте выбранный Xcode и установленный runtime; не удаляйте данные симулятора и не переустанавливайте Xcode до локализации сбоя. Этот порядок подходит, если сборка проекта проходит, но Flutter не показывает устройство или не может запустить симулятор.
- Flutter-разработчикам — если после обновления Xcode перестали работать
flutter devicesили запуск iOS Simulator. - Инженерам CI — если удалённая сборка проходит, а обнаружение или запуск симулятора завершается ошибкой.
- Сопровождающим платформу — если нужно отличить проблему Flutter SDK от неверного Xcode или отсутствующего runtime.
Срез на 30 сентября 2026 года. В примечаниях Flutter 3.47.0 зафиксирована обработка пути DeviceHub.app; документация Flutter также различает Device Hub в Xcode 27 и прежнее приложение Simulator. Это изменение не означает, что оно устраняет любые сбои запуска: проверяйте каждый этап отдельно по примечаниям Flutter 3.47.0 и руководству Flutter по настройке iOS.
Flutter 3.47 и Xcode 27: где теряется симулятор
В этой связке важно разделить три события: сборку, обнаружение устройства и запуск симулятора. Успешный xcodebuild подтверждает только прохождение сборочного этапа для заданной конфигурации. Он не доказывает, что Flutter нашёл устройство, и не гарантирует, что графическая сессия симулятора стартует.
| Наблюдение | Вероятная область проверки | Следующий безопасный шаг |
|---|---|---|
Сборка проходит, но flutter devices не показывает симулятор |
Путь обнаружения устройств во Flutter, активный SDK, выбор Xcode | Записать пути и версии, затем проверить поддержку DeviceHub.app |
| Устройство отображается, но запуск завершается ошибкой | Runtime, доступность устройства, запуск графической среды | Повторить запуск через инструменты Xcode и проверить runtime |
| Локально работает, в CI не работает | Различие пользователя, PATH, Flutter SDK или выбранного Xcode |
Снять те же диагностические данные непосредственно в окружении Runner |
| Не работает и из интерфейса Xcode | Runtime или состояние установки Xcode | Проверить доступные компоненты и журналы, не очищая данные заранее |
С Xcode 27 управление симуляторами связано с Device Hub. В официальном описании Xcode 27 и материалах Flutter указано изменение относительно более раннего входа через Simulator: описание Xcode 27 и документация Flutter для iOS. Поэтому старый инструмент, который по-прежнему ищет Simulator.app в прежнем месте, может не обнаружить устройство. Но похожий симптом возникает и при неверно выбранном Xcode, отсутствующем runtime или разном окружении терминала и CI.
Проверка старого пути и версии Flutter
Если flutter devices не выводит доступный симулятор, сначала выясните, какой SDK реально запущен. Название версии в IDE или настройках проекта не всегда совпадает с бинарным файлом, который получает терминал. В CI ситуация усложняется: Runner может использовать отдельный PATH, установленный для служебной учётной записи.
В терминале из каталога проекта выполните:
which flutter
flutter --version
flutter doctor -v
Запишите полный путь к исполняемому файлу, сведения о версии и блок диагностики Xcode. Затем сравните их с настройками IDE и выводом CI. Если используется менеджер версий Flutter, проверьте активную версию именно для текущего проекта, а не только глобальную установку. Не ограничивайтесь командой flutter --version: она не показывает, совпадает ли вызванный бинарный файл с тем, который настроен в IDE или Runner.
Flutter 3.47.0 содержит изменение, связанное с путём к DeviceHub.app; это подтверждают официальные примечания к выпуску. Кроме того, соответствующая запись в системе отслеживания Flutter помогает сверить формулировку проблемы и её исправления. Используйте эти источники как основание для выбора версии, но не трактуйте изменение пути как гарантию исправления runtime или проблем запуска.
Если SDK старше версии с нужной обработкой, обновите его либо зафиксируйте совместимую версию в контролируемой конфигурации проекта. Перед изменением сохраните текущий вывод flutter --version и путь из which flutter. Для CI зафиксируйте ту же информацию в логе задания — иначе изменение версии на узле может остаться незаметным и воспроизводимость пропадёт.
Не удаляйте папку с данными симуляторов, пока не подтвердили, что Flutter и инструменты Xcode не видят устройство. Очистка может стереть локальное состояние тестов и не исправить неверный путь к приложению или SDK; перед ней сохраните журналы и определите, как восстановить нужные тестовые данные.
Выбор Xcode: терминал против IDE и CI
Следом проверьте, какой Xcode выбран в каждом месте запуска. На одном Mac могут находиться несколько установок или разные командные инструменты; терминал, IDE и CI при этом способны обращаться не к одной и той же версии. Отображаемая в интерфейсе версия сама по себе не подтверждает, какой каталог использует конкретный процесс.
Снимите данные из того же терминала и под той же учётной записью, где возникает ошибка:
xcode-select -p
xcodebuild -version
Первую команду сопоставьте с ожидаемым каталогом Xcode, вторую — с версией в принятой конфигурации команды. Синтаксис и назначение средств командной строки описаны в справке Apple по инструментам Xcode. Если путь отличается, не меняйте выбор вслепую на общем узле: сначала выясните, какие задания используют текущую настройку, затем согласуйте изменение с владельцами сборочного контура.
В IDE проверьте путь к Flutter SDK и конфигурацию инструментов. В CI выведите which flutter, flutter --version, xcode-select -p и xcodebuild -version прямо в том задании, где обнаруживается ошибка. Сравнивайте не только номера версий, но и сами пути. Если локальный запуск и CI используют разные SDK или Xcode, это уже отдельная причина расхождения, даже когда обновление Flutter исправлено.
Device Hub открыт, но Flutter не показывает устройство
Если Device Hub отображает доступный симулятор, а flutter devices его не выводит, проверяйте слои по очереди. Убедитесь, что команда запускается из нужного проекта и использует ожидаемый Flutter SDK. Затем проверьте, что выбранный через xcode-select Xcode совпадает с тем, в котором вы открыли Device Hub.
Выполните flutter devices и сохраните полный вывод. Если доступен выбранный симулятор, попробуйте запустить на нём приложение средствами Flutter из каталога проекта. После этого отдельно проверьте список устройств и запуск через интерфейс Xcode или соответствующие инструменты Xcode. Такая пара проверок отвечает на ключевой вопрос: не распознаётся ли устройство только Flutter, или запуск не работает и вне Flutter.
Результаты интерпретируйте так:
- Xcode показывает и запускает устройство, Flutter его не показывает. Вернитесь к версии Flutter, пути SDK, каталогу проекта и выбранному Xcode. Если используется устаревший SDK, проверьте изменение
DeviceHub.appв примечаниях Flutter 3.47.0. - Обе стороны показывают устройство, но запуск падает только из Flutter. Зафиксируйте текст ошибки, выбранный идентификатор устройства и команду запуска. Проверьте, не подхватывается ли другая конфигурация проекта.
- Устройство доступно, но запуск не удаётся и средствами Xcode. Перейдите к проверке runtime и журналов запуска; проблема уже не сводится к пути обнаружения Flutter.
- В списке Xcode нет подходящего устройства. Проверьте, установлен ли требуемый runtime и распознаётся ли он активной установкой Xcode.
Возможность управления установленными компонентами и симуляторами сверяйте с инструкцией по загрузке и установке дополнительных компонентов Xcode и примечаниями к Xcode 27. Если runtime отсутствует, сначала установите или выберите нужный компонент штатным способом, а затем повторите проверку из Xcode и Flutter. Не удаляйте существующие устройства ради проверки: это не устанавливает недостающий runtime и может уничтожить тестовое состояние.
Удалённый Mac CI: отличия учётной записи и Runner
На удалённом Mac команды разработчика и CI могут выполняться в разных пользовательских окружениях. Это влияет на PATH, доступ к Flutter SDK и настройки Xcode. Поэтому результат из интерактивного SSH-сеанса нельзя автоматически считать результатом Runner: важны именно команды, запущенные в контексте задания.
Добавьте диагностический шаг до обновления или очистки узла. Сохраните каталог проекта, путь к Flutter, вывод flutter --version, результат xcode-select -p, версию xcodebuild, вывод flutter devices и часть журнала с ошибкой. Не помещайте в публичные артефакты секреты или содержимое переменных окружения, не относящихся к диагностике.
Если в одном узле несколько проектов, сравните их рабочие каталоги и конфигурацию SDK. Убедитесь, что запуск не зависит от случайного текущего каталога или от настройки, заданной только в интерактивной оболочке. При исправлении сначала измените один фактор — например, выбранный Flutter SDK. Повторите задание, а затем отдельно проверьте выбор Xcode или runtime. Такой порядок показывает, какое именно изменение повлияло на результат.
Не обновляйте общий узел до того, как снимете исходные данные. Обновление может одновременно изменить версии Flutter и Xcode, после чего будет сложнее понять причину сбоя. Если изменение нужно проверить срочно, используйте отдельную тестовую конфигурацию или узел, а действующий CI оставьте воспроизводимым до завершения проверки.
Приёмка исправления в реальном проекте
Исправление считается подтверждённым не по одному сообщению об обнаруженном устройстве. Проверьте отдельно обнаружение, запуск приложения и выполнение нужного тестового задания. Запускайте команды из каталога проекта и с тем же набором настроек, который использует CI.
- [ ] Сохраните исходные пути и версии Flutter и Xcode до изменений.
- [ ] Убедитесь, что терминал, IDE и CI вызывают ожидаемый Flutter SDK.
- [ ] Проверьте, что активен нужный каталог Xcode, а не другая установка.
- [ ] Убедитесь, что требуемый runtime доступен и устройство отображается средствами Xcode.
- [ ] Повторите
flutter devicesи сохраните полный результат. - [ ] Запустите приложение на целевом симуляторе средствами Flutter.
- [ ] Выполните тестовую задачу проекта в том же окружении, где возникал сбой.
- [ ] Сопоставьте результат до и после изменения, включая журналы и выбранные пути.
Если Xcode видит и запускает устройство, а Flutter после фиксации корректного SDK всё ещё его не перечисляет, продолжайте исследовать путь обнаружения и конфигурацию Flutter. Если не удаётся запустить симулятор из обоих инструментов, сосредоточьтесь на runtime и состоянии Xcode. Если локально тест проходит, а удалённое задание падает, сначала сравните пользовательское окружение и пути Runner; сбрасывать общий узел до такого сравнения не следует.
Для надёжной приёмки сохраните в журнале проекта использованные версии и пути. Повторите тест после следующего изменения Flutter или Xcode, которое затрагивает поддержку Device Hub: официальные примечания к выпуску и документация — точки для повторной сверки, а не замена тестированию собственного проекта. Так вы сможете отличить повторное изменение инструментария от локальной поломки runtime.
Когда проблема действительно связана с отсутствием постоянной среды macOS, а не с неправильным выбором SDK, удалённый Mac может быть удобен для воспроизводимой сборки и проверки симулятора. Но сначала сравните такой вариант с вашей текущей машиной: Linux-узел не заменит инструменты Xcode, а общий CI-узел без закреплённых версий может сохранить ту же проблему. Аренда не нужна, если у вас уже есть подходящий Mac и нагрузка стабильна; она разумна для временной проверки или отдельного CI-контура, когда покупка отдельного оборудования не оправдана. Перед решением посмотрите условия и стоимость аренды Mac, а если нужен отдельный узел для проверки реального Flutter-проекта, изучите доступные варианты аренды Mac в VMSPIN.