Статус «Mac подключён, но сборка .NET MAUI iOS завершилась ошибкой» обычно означает не одну, а несколько разных проблем: соединение, рабочую нагрузку, Xcode, кэш или подпись.
Сначала запустите минимальный проект непосредственно на удалённом Mac и проверьте совместимость .NET for iOS с Xcode 26.6. Если локальная сборка Mac тоже не проходит, исправляйте инструментальную цепочку; если Mac собирает проект, сохраняйте узел и проверяйте Pair to Mac, удалённый SDK и параметры Windows. Пересоздание узла оставляйте только для среды, которую нельзя зафиксировать или которая продолжает самопроизвольно расходиться.
Кому пригодится эта схема
Материал предназначен разработчикам, которые используют Visual Studio в Windows для сборки .NET MAUI iOS и получают ошибку уже после успешного подключения к Mac.
Он также полезен DevOps-инженерам, поддерживающим удалённый Mac как узел CI, и руководителям мобильных команд, которым нужно решить, продолжать обновление, временно откатиться или разделить версии инструментов.
Последняя проверка материала выполнена 5 сентября 2026 года по документации Microsoft Learn для .NET MAUI 10, записям dotnet/macios и официальным релизам .NET MAUI. Повторная проверка нужна после нового сервисного выпуска .NET MAUI 10, изменения требований Xcode, обновления документации Pair to Mac или модернизации узла.
Снимок доказательств перед исправлением
Первый ошибочный текст важнее последней строки вроде «Build failed». Перед изменениями сохраните полный бинарный или текстовый журнал и зафиксируйте одинаковые входные условия:
- версию .NET SDK на Windows и Mac;
- список рабочих нагрузок и их манифесты;
- фактическую версию .NET for iOS;
- выбранный путь к Xcode;
- целевой фреймворк, конфигурацию и RuntimeIdentifier;
- адрес Mac, учётную запись, порт и способ аутентификации;
- команду запуска и каталог проекта.
Официальная документация описывает Pair to Mac как механизм, при котором Visual Studio обращается к удалённому Mac по SSH для выполнения операций сборки; поэтому факт «узел отображается как подключённый» ещё не доказывает, что удалённый SDK и Apple-инструменты готовы к работе. Детали последовательности подключения следует сверять с описанием Pair to Mac и SSH.
Диагностику удобно разделить на четыре независимых состояния:
- Соединение Pair to Mac установлено. Windows видит узел и может пройти аутентификацию.
- Минимальный проект собирается на Mac. Локально работают SDK, рабочая нагрузка и Xcode.
- Проект собирается через Windows. Удалённые каталоги, параметры и кэш согласованы.
- Подписанное приложение публикуется. Сертификаты, профиль, связка ключей и устройство доступны в нужном контексте.
Переход к следующему состоянию выполняйте только после фиксации результата предыдущего. Это не позволяет лечить ошибку подписи переустановкой Xcode или чистить кэш, когда причиной является неверная учётная запись.
Минимальная сборка на Mac
Для начала создайте временный проект с нейтральным именем, например SampleMauiIos, и разместите его в отдельном каталоге. Не используйте сразу рабочий репозиторий: его obj, локальные свойства и секреты могут скрыть проблему.
На Mac проверьте следующие пункты:
- установлен ли ожидаемый .NET SDK;
- присутствует ли рабочая нагрузка, содержащая .NET for iOS;
- какой путь возвращает
xcode-select; - не переопределяет ли
DEVELOPER_DIRсистемный выбор; - открывается ли нужная версия Xcode и подтверждена ли лицензия;
- совпадает ли целевой фреймворк с установленным набором инструментов.
Если проект не проходит минимальную сборку непосредственно на Mac, остановите проверку Pair to Mac. Это уже неисправность среды: рабочей нагрузки, версии .NET for iOS, Xcode или выбранного каталога разработчика. Сопоставьте требования текущей ветки MAUI с официальной документацией .NET MAUI 10, а поддержку Xcode 26.6 — с актуальной записью dotnet/macios.
Если локальная сборка проходит, сохраните журнал как эталон и передайте его ответственному за подключение. Дальше изменение пакетов на Mac без основания не требуется.
Ответственность Windows-разработчика
Для разработчика, работающего в Windows, ключевая задача — отделить обнаружение узла от аутентификации и от запуска удалённой службы.
Проверяйте в таком порядке:
- адрес Mac разрешается и доступен по нужному порту;
- указанная учётная запись существует на Mac и имеет разрешённый вход;
- SSH-ключ соответствует этой учётной записи;
- после входа удалённая команда действительно запускается;
- Visual Studio использует тот же узел, который был проверен вручную;
- пустой MAUI-проект повторяет результат рабочего проекта.
Если узел не находится, сначала проверяйте сеть, имя хоста и порт. Если система находит Mac, но снова просит пароль, исследуйте ключ, пользователя и сохранённую запись подключения. Если аутентификация проходит, но инициализация завершается ошибкой, переходите к удалённому SDK и разрешениям каталога.
Старую запись Visual Studio не следует удалять автоматически. Сначала экспортируйте доступные параметры, зафиксируйте рабочий адрес и создайте отдельное подключение с новым понятным именем. Удаление ключа или полное очищение учётных данных может лишить доступа к другим проектам; выполнять это допустимо только после подтверждения, что ключ можно выпустить заново и что у команды есть резервный способ входа.
Стоп-условие для этого этапа простое: если пустой проект не может пройти тот же удалённый маршрут, бизнес-код приложения не имеет отношения к проблеме. Результат передаётся DevOps-инженеру вместе с журналом подключения, но без паролей и содержимого приватного ключа.
Согласование .NET MAUI 10 и Xcode 26.6
Версия установленного пакета MAUI не является достаточным доказательством готовности iOS-сборки. Необходимо сопоставить как минимум четыре элемента: .NET SDK, манифест рабочей нагрузки, .NET for iOS и выбранный Xcode.
Проверяйте не только системный Xcode, но и фактический путь, который видит процесс сборки:
- значение
xcode-select; - переменную
DEVELOPER_DIR, если она задана; - настройки Xcode в IDE;
- путь, используемый командой CI;
- права учётной записи, запускающей сборку.
Когда на узле установлено несколько версий Xcode, глобальное переключение может исправить один проект и одновременно сломать другой. Безопаснее применять выбор версии на уровне конкретной задачи или изолировать проекты по узлам. После смены пути повторяйте минимальную сборку на Mac, а не сразу запускайте полноценный архив.
Официальная документация Microsoft содержит отдельные рекомендации по выбору Xcode и диагностике ошибок; их следует сопоставлять с руководством по устранению неисправностей .NET MAUI. Если текущая рабочая нагрузка требует другой версии Xcode, зафиксируйте это как изменение инструментария, а не как временный сбой Pair to Mac.
Решение о временном откате принимайте только после сравнения минимального проекта и рабочего приложения. Если старый набор собирает оба проекта, а новый не собирает даже минимальный, допустим изолированный возврат для непрерывности релиза. Если новый набор работает на Mac, но ломается через Windows, откат скрывает настоящую проблему удалённого маршрута.
Проверка удалённого SDK и кэша
CI-инженеру нужно сравнить не экран Visual Studio, а фактические параметры двух запусков. В журнале должны быть видны адрес Mac, учётная запись, порт, каталог удалённого SDK, входной проект и целевой фреймворк.
Выполните пять действий:
- Запустите сборку из Windows командной строкой с теми же параметрами, что использует IDE.
- Сравните её с локальной командой на Mac для минимального проекта.
- Проверьте, не остались ли в
objи промежуточных каталогах артефакты другой версии SDK. - Повторите тест из чистого клона репозитория.
- Сохраните первый результат до очистки, чтобы иметь точку сравнения.
Очистка кэша допустима только при конкретном признаке рассогласования: например, журнал явно указывает на старый путь, несовместимый артефакт или результат предыдущей версии рабочей нагрузки. Перед удалением сохраните список каталогов и команду восстановления. Полная очистка obj, bin или удалённого кэша увеличивает время повторной проверки и может удалить артефакт, необходимый для сравнения.
Не смешивайте три операции: очистку промежуточных файлов, переустановку рабочей нагрузки и удаление ключей. У каждой разный радиус воздействия. Переустановка нужна только при повреждённой или неполной рабочей нагрузке; удаление ключей — только при подтверждённой проблеме аутентификации; очистка — только при доказанном загрязнении артефактами.
Для командной публикации используйте отдельный воспроизводимый запуск по инструкции .NET MAUI для публикации из CLI. Чистый клон и зафиксированный набор инструментов показывают, была ли причина в скрытом состоянии рабочей станции разработчика.
Подпись, устройство и архив
Когда Debug или симулятор собираются, а Release, физическое устройство или архив завершаются ошибкой, соединение Pair to Mac уже нельзя считать главным подозреваемым.
Ответственный за выпуск проверяет отдельно:
- идентификатор подписи и его срок действия;
- профиль подготовки и соответствие идентификаторов;
- наличие сертификата и закрытого ключа в нужной связке ключей;
- учётную запись и контекст процесса, запускающего CI;
- RuntimeIdentifier;
- видимость подключённого устройства на удалённом Mac;
- различия между Debug и Release.
Сначала выполните компиляцию без подписи, если такой режим соответствует текущей задаче. Затем проведите минимальный подписанный тест с тестовым идентификатором и только после этого возвращайте полноценное архивирование. Это позволяет понять, сломалась ли компиляция, выбор runtime или доступ к секретам.
Не переносите сертификаты в журналы и не передавайте приватные ключи через параметры командной строки. Если подпись работает вручную, но не в CI, сравните учётную запись процесса, связку ключей и переменные среды. Передача результата должна включать название конфигурации, целевой runtime и тип ошибки, но не секретные материалы.
Решение для владельца платформы
Владельцу платформы нужна не ещё одна попытка сборки, а матрица решений:
| Наблюдение | Вероятный слой | Действие | Когда остановиться |
|---|---|---|---|
| Минимальный проект не собирается на Mac | Xcode, .NET SDK или рабочая нагрузка | Зафиксировать версии и исправить инструментальную цепочку | Не возвращаться к Pair to Mac, пока Mac не собирает локально |
| Mac собирает, Windows не подключается | Сеть, SSH или учётная запись | Восстановить отдельное подключение и проверить пустой проект | Передать DevOps, если локальный SSH проходит, а служба нет |
| Mac и Windows собирают минимальный проект, приложение нет | Проект, свойства или кэш | Сравнить чистый клон, фреймворк и промежуточные файлы | Не переустанавливать Xcode без доказательства |
| Сборка проходит, публикация нет | Подпись, профиль, устройство или runtime | Провести минимальный подписанный тест | Эскалировать владельцу релиза с полным журналом |
| Несколько проектов нестабильны после перезапуска | Дрейф или повреждение узла | Зафиксировать среду, затем оценить отдельный узел | Пересоздавать узел только после сохранения доказательств |
Оставляйте существующий Mac, если локальная минимальная сборка проходит, версии можно зафиксировать, а сбой воспроизводится только через Windows. В таком случае исправляйте подключение, удалённый SDK или кэш.
Разделяйте версии по задачам, если нескольким проектам нужны разные Xcode и рабочие нагрузки. Пересоздание узла оправдано только тогда, когда несколько проектов дают непредсказуемые результаты, состояние не восстанавливается после перезапуска, а чистая изоляция невозможна. До этого сохраните конфигурацию, журналы, список секретов и процедуру повторного подключения.
Финальная приёмка должна включать отключение и повторное подключение, перезапуск Mac, чистый клон, локальную сборку, удалённую сборку и одну настоящую задачу публикации. Если хотя бы один из этих сценариев не проверен, узел нельзя считать готовым для постоянного CI.
Часто задаваемые вопросы
Развёрнутые ответы на типовые поисковые сценарии собраны ниже, чтобы не смешивать разные уровни неисправности.
Когда вместо ремонта нужен отдельный Mac
Если существующий Mac нельзя привести к воспроизводимому состоянию, отдельный удалённый Mac может быть полезнее бесконечной очистки рабочей станции. Такой вариант имеет смысл после успешной минимальной проверки: на новом узле сначала фиксируются .NET SDK, рабочая нагрузка, .NET for iOS и Xcode 26.6, затем проверяются Pair to Mac, чистая сборка и подписанный тест.
У удалённого узла есть реальные преимущества для временного эксперимента: не требуется покупать отдельную физическую машину, можно сохранить полный доступ администратора и не смешивать новый набор инструментов с уже работающим релизом. Но это не отменяет инженерную проверку: нестабильная конфигурация просто переместится на другой Mac.
Если текущая схема построена на Windows и локальном Mac, её слабые места обычно связаны с невозможностью изолировать версии Xcode, зависимостью от включённого рабочего компьютера и скрытым состоянием SSH или связки ключей. В такой ситуации аренда удалённого Mac через RUVCLOUD может дать отдельный узел для проверки, однако мигрировать официальный релиз следует только после прохождения всей матрицы приёмки.
Для временной ветки, теста новой версии .NET MAUI или параллельной проверки Xcode это рациональнее, чем немедленно менять рабочую среду. Для постоянной тяжёлой нагрузки, требования к физическому USB-устройству или особым аппаратным интерфейсам локальный Mac может оставаться более подходящим вариантом.
Если нужен конкретный узел под регион или отдельный экспериментальный контур, параметры доступных вариантов следует проверять на странице заказа удалённого Mac. Сначала должна быть доказана воспроизводимость сборки, а уже затем принимается коммерческое решение.
Для разработчика, который уже несколько раз очищал кэш, менял Xcode и повторно создавал подключение без единого снимка доказательств, наиболее экономным следующим шагом будет не очередная переустановка, а изолированный тестовый узел. Он позволит отделить ошибку проекта от дрейфа среды и подтвердить, что Pair to Mac, чистая сборка и подпись образуют рабочую цепочку.