Удалённый Mac 24 августа 2026 г. ~12 мин SwiftUI Xcode Previews

SwiftUI Preview не работает: руководство по диагностике удалённого Mac 2026

Руководство предназначено для независимых разработчиков и небольших команд, у которых Canvas не запускается, бесконечно обновляется или показывает неверный результат. Мы разделяем диагностику кода, зависимостей, SwiftData, Target, симулятора и удалённой macOS-сессии, чтобы не удалять кэш вслепую.

SwiftUI Preview не работает: руководство по диагностике удалённого Mac 2026

Руководство предназначено для независимых разработчиков и небольших команд, у которых Canvas не запускается, бесконечно обновляется или показывает неверный результат. Мы разделяем диагностику кода, зависимостей, SwiftData, Target, симулятора и удалённой macOS-сессии, чтобы не удалять кэш вслепую.

В примечаниях к выпуску Xcode 14 Apple отдельно описывает вход в диагностику SwiftUI Preview через Canvas и диагностический отчёт: это официальный инструмент, а не сторонний способ сбора логов (описание Preview Diagnostics в Xcode 14). Поэтому при симптоме «SwiftUI Preview не работает» не начинайте с удаления всей DerivedData или переустановки Xcode: сначала сохраните отчёт и определите, сломалась ли цепочка на уровне представления, зависимостей, runtime или среды macOS.

Симптом → самый быстрый путь

  • Canvas не запускается или сразу закрывается — экспортируйте диагностику, затем соберите минимальное представление без внешних данных.
  • Preview бесконечно обновляется — проверьте графическую сессию, Simulator runtime, владельца каталогов и только после этого локально очистите DerivedData.
  • Симулятор запускает приложение, но Preview не открывается — рассматривайте это как две разные цепочки проверки, а не как доказательство исправности проекта.

Эта статья предназначена для независимых разработчиков, которые используют SwiftUI Preview для итерации интерфейса, но Canvas не стартует или не обновляется. Она также пригодится разработчикам, у которых приложение работает в Simulator, а Preview выдаёт ошибку, и небольшим командам, поддерживающим рабочее место через VNC или удалённый рабочий стол.

01

Сначала фиксируем границу неисправности

Xcode Previews — это не просто уменьшенная кнопка запуска уже собранного приложения. Apple описывает предпросмотр как отдельный способ увидеть SwiftUI-представление в Canvas, а макрос #Preview задаёт точку, из которой Xcode должен создать это представление (официальное описание Previews в Xcode). В результате один и тот же проект может успешно проходить обычную сборку и при этом не создавать экземпляр для Canvas.

Перед любым изменением запишите:

  • имя рабочей схемы и Target;
  • выбранную платформу — iOS или macOS;
  • устройство либо Simulator runtime;
  • текст первой ошибки и момент её появления;
  • состояние проекта до и после последнего изменения;
  • минимальный файл, на котором сбой можно повторить.

Затем откройте Canvas, вызовите меню диагностики и экспортируйте отчёт. Сохраните его рядом с обезличенной копией проекта. Имена пользователей, названия модулей, пути и идентификаторы приложения в публикации или обращении в поддержку заменяйте на значения вроде <PROJECT_DIR>, <MODULE_NAME> и <USER>.

Не смешивайте три результата:

  1. проект компилируется через обычную команду Build;
  2. приложение запускается на Simulator или физическом устройстве;
  3. Preview создаёт и отображает конкретное представление.

Проверка запуска приложения описана Apple отдельно от работы Canvas (документация по запуску приложения на симуляторе и устройстве). Такой порядок сразу убирает распространённую ошибку: считать, что исправный Simulator автоматически означает исправный Preview.

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

02

Первая проверка: простой SwiftUI-проект без внешних зависимостей

Для проекта с одним Target начните не с настроек macOS, а с самого представления. В файле должен быть корректный макрос предпросмотра, а код внутри него обязан создавать View без скрытого требования к производственной среде.

Пример безопасной основы:

#Preview {
    ProductCard(
        item: PreviewData.sampleProduct
    )
}

Название типа и тестовых данных здесь условные. В реальном проекте проверьте, что файл действительно принадлежит нужному Target и что используемый тип доступен для этой платформы.

Дальше действуйте по нарастающей сложности:

  1. Создайте минимальное представление с одним Text или простым контейнером.
  2. Убедитесь, что оно появляется в Canvas без сетевых запросов и чтения базы данных.
  3. Добавьте фиксированную модель и тестовые значения.
  4. Подключите Environment, наблюдаемое состояние и модификаторы по одному.
  5. После каждого изменения обновляйте Preview и отмечайте первый шаг, на котором он перестал создаваться.

Особое внимание уделите коду, который вызывается в инициализаторе View. Запрос к API, обращение к Keychain, чтение файла из недоступного каталога, ожидание авторизации или создание глобального синглтона могут быть допустимы в полном приложении, но непредсказуемы в среде предпросмотра.

Если минимальный View не работает, а новый пустой проект с таким же простым представлением работает, проблема, скорее всего, находится в конфигурации исходного проекта. Если не работает и новый проект, переходите к проверке runtime и среды. Это более полезное разделение, чем общий совет «перезапустите Xcode».

03

Данные, SwiftData и внешние сервисы отделяем от интерфейса

Данные — наиболее частая причина, по которой визуально простой экран оказывается сложным для Preview. Экран может ожидать пользователя, токен, мигрированную базу, активную сеть или уже инициализированный контейнер. Canvas не должен зависеть от состояния, которое невозможно воспроизвести в чистом запуске.

Для data-driven App подготовьте отдельный контур предпросмотра:

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

При проблеме со SwiftData не объединяйте три разных диагноза. Ошибка создания контейнера означает одно; успешно созданный контейнер без объектов — другое; падение при рендеринге конкретного View — третье. В отчёте диагностики ищите место, где впервые нарушилась последовательность, а не последнее сообщение «Preview failed».

Для моделей удобно иметь фабрику вроде PreviewData.sampleContainer, но её реализация должна явно отличаться от производственной. Если Preview вызывает тот же singleton, что и основное приложение, тест перестаёт быть изолированным. Такой подход затрудняет ответ на главный вопрос: сломан SwiftUI-код или недоступна инфраструктура данных.

Apple Developer Forums полезны для поиска похожих симптомов, включая ошибки прав, загрузки и нестабильность отдельных версий, но обсуждение сообщества следует считать диагностической подсказкой, а не доказательством общего дефекта (раздел Xcode Previews на Apple Developer Forums). Отдельные ответы сотрудников Apple также нужно отличать от формальной документации и release notes.

04

Target, Swift Package и ресурсы: проверяем границы загрузки

Сообщение Runtime Linking Failure обычно требует анализа первой ошибки связывания, а не повторного удаления всех пакетов. В проекте может быть успешно разрешена зависимость, успешно выполнена обычная компиляция, но Preview всё равно не сможет загрузить нужный продукт или ресурс во время выполнения.

Проверьте по порядку:

  • входит ли файл с #Preview в правильный Target;
  • совпадает ли активная Scheme с выбранным приложением;
  • добавлен ли продукт Swift Package в нужный Target;
  • совместимы ли платформа и архитектура зависимости;
  • присутствуют ли изображения, шрифты и JSON в Copy Bundle Resources;
  • не используется ли ресурс только в основном приложении, но не в Preview-контуре.

Общие параметры Target задаются отдельно от Build Phases; Apple описывает создание и настройку Target в соответствующей документации (настройка нового Target в Xcode). Проверку связывания и копирования ресурсов проводите в Build Phases, где видны конкретные продукты и файлы (настройка Build Phases).

В диагностическом отчёте полезно найти первое сообщение наподобие «symbol not found», «image not found» или «module could not be loaded». Последующие сообщения Canvas часто лишь описывают последствия. Названия пакетов, модулей и путей в рабочих заметках лучше заменять на <PACKAGE_PRODUCT>, <FRAMEWORK> и <RESOURCE_PATH>.

Удаление Package.resolved может заставить менеджер зависимостей пересобрать граф, но одновременно скрывает исходное состояние проекта. Такой шаг оправдан только после сохранения файла, фиксации версии зависимостей и проверки, что причина действительно связана с разрешением пакетов.

05

Сводное сравнение перед изменением среды

Сигнал Что уже подтверждено Следующая проверка Преждевременное действие
Минимальный Text работает, полный экран нет Canvas и базовый runtime доступны Данные, Environment, ресурсы и зависимости Переустановка Xcode
Симулятор запускает App, Preview не создаётся Обычная сборка и runtime приложения работают Макрос Preview, инициализация View, Target Вывод о поломке всего Xcode
Runtime Linking Failure Сбой происходит при загрузке Preview Target Membership, Build Phases, пакет и символ из первой ошибки Удаление всех пакетов
Новый проект также не показывает Canvas Проблема может быть вне исходного кода Сессия входа, runtime, каталоги и права Бесконечное изменение SwiftUI-кода
Сбой появляется только в удалённой сессии Есть корреляция со способом доступа к Mac Полноценный графический вход и владельцы каталогов Безусловная выдача Full Disk Access

По нашей оценке для диагностики такой таблицы достаточно, чтобы разделить четыре направления: код, проект, runtime и среда. Это не рейтинг производительности и не универсальный тест совместимости; оценка относится только к порядку принятия решения.

06

Удалённый Mac: проверяем сессию и права до очистки

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

Проверьте следующие каталоги:

  • проект и его рабочую копию;
  • каталог DerivedData;
  • данные Simulator;
  • временные каталоги, которые использует сборка;
  • расположение пакетов и локальных ресурсов.

У каждого пути должен быть корректный владелец и возможность чтения и записи для текущего пользователя. Сравните поведение проекта в обычном каталоге пользователя и в защищённом или синхронизируемом каталоге. Если в одном месте минимальный Preview работает, а в другом нет, это сильный признак проблемы доступа или файлового наблюдателя.

Не выдавайте приложению или Xcode полный доступ к диску без конкретной причины. Сначала определите, какой путь блокируется, изучите сообщение в журнале и проверьте более узкое разрешение. Если проблема связана с тем, что проект находится в каталоге с ограничениями macOS, безопаснее перенести тестовую копию в обычный рабочий каталог и повторить эксперимент.

После этого проверьте выбранный runtime. Он должен быть установлен и запускаться отдельно через Simulator. Если сам runtime не стартует, бессмысленно исправлять SwiftUI Preview — сначала восстанавливается платформа выполнения.

Для команд, которые используют удалённое рабочее место постоянно, полезно заранее изучить настройку удалённого Mac для Xcode и приёмку проекта. Это не заменяет диагностику конкретного Preview, но помогает заранее проверить графический вход, доступ к каталогам и работу инструментов в реальной сессии.

07

Локальная очистка DerivedData только после фиксации причины

Удаление DerivedData может помочь, если промежуточный продукт или индекс проекта повреждён. Оно не исправит неверный Target, отсутствующий символ, недоступную базу, неправильный runtime или отсутствие графической сессии.

Безопасный порядок выглядит так:

  1. Экспортируйте Previews Diagnostics и сохраните текст ошибки.
  2. Закройте Xcode, чтобы он не продолжал писать в рабочие каталоги.
  3. Определите DerivedData именно этого проекта, а не всей системы.
  4. Сохраните резервную копию или хотя бы запишите исходный путь.
  5. Удалите только выбранный промежуточный каталог.
  6. Запустите Xcode и повторите минимальный Preview.
  7. Затем проверьте полный экран, зависимые данные и перезапуск среды.

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

Для повторяемой работы команды фиксируйте: версию Xcode, версию macOS, выбранный runtime, схему, способ подключения, расположение проекта, действие по восстановлению и результат после перезапуска. Если позже появится похожий сбой, эта запись покажет, что уже проверялось, и не заставит снова начинать с полной очистки.

08

Ремонт выбираем по результату минимального теста

Используйте следующие условия, а не общий список советов:

  • Если минимальный View работает, а экран с данными нет, выбирайте изоляцию SwiftData, API, авторизации и Environment; иначе переходите к проверке Target и среды.
  • Если первая ошибка указывает на символ, модуль или ресурс, выбирайте проверку Swift Package и Build Phases; иначе не удаляйте Package.resolved автоматически.
  • Если новый проект работает локально, а исходный — нет, выбирайте ремонт проекта; иначе проверяйте runtime, графический вход и каталоги.
  • Если сбой появляется только через удалённую сессию, выбирайте повторную проверку полноценного входа и прав; иначе не объявляйте VNC причиной без сравниваемого теста.
  • Если локальная очистка помогает один раз, но после перезапуска Preview снова ломается, выбирайте анализ причины повреждения артефактов, а не повторное удаление кэша.
  • Если минимальный проект стабильно не работает даже после проверки среды, выбирайте подготовку обезличенного проекта и логов для Apple, используя официальные рекомендации по профилям и журналам Swift.
09

FAQ: ответы на типовые сбои Canvas

Cannot preview in this file

Сначала проверяется первая ошибка в диагностике, затем Target Membership и макрос предпросмотра. Если файл компилируется, но View требует производственную базу или сеть, замените их фиксированными тестовыми зависимостями. Отдельный минимальный проект показывает, относится ли ошибка к конкретному файлу или к рабочей среде.

Simulator работает, а Preview — нет

Это нормальная диагностическая развилка: запуск приложения и создание экземпляра для Canvas — разные операции. В Preview могут выполняться другой путь инициализации, загрузка ресурсов и создание тестовых данных. Поэтому исправный Simulator сокращает область поиска, но не закрывает её. Проверяйте View от простого к сложному, не меняя одновременно Scheme, Target и runtime.

Runtime Linking Failure

Ищите самое раннее сообщение о невозможности найти символ, модуль, фреймворк или ресурс. После этого сверяйте продукт пакета, Build Phases, платформу и принадлежность файла к Target. Если ошибка появилась после изменения зависимостей, сохраните состояние разрешённых версий и только затем выполняйте локальные действия с кэшем.

Бесконечное обновление на удалённом Mac

Сначала проверяются полноценная графическая сессия и запуск Xcode после входа пользователя. Затем сравниваются проект в обычном каталоге, DerivedData, данные Simulator и временные файлы. Если новый проект ведёт себя так же, проблема, вероятно, не в конкретном View. Перенос рабочей копии или смена среды рассматриваются только после этих сравнений.

10

Приёмка восстановленной среды для постоянной работы

После исправления не ограничивайтесь одним удачным появлением Canvas. Проведите последовательную приёмку:

  1. статический Preview простого View;
  2. Preview с фиксированными тестовыми данными;
  3. экран с Environment и наблюдаемым состоянием;
  4. представление с локальным ресурсом или пакетом;
  5. повторная проверка после полного перезапуска Xcode;
  6. повторная проверка после нового входа в удалённую графическую сессию.

Запишите, какой тест прошёл, какой runtime выбран и какой каталог использовался. Для длительной разработки важна не случайная успешная отрисовка, а способность восстановить тот же результат после перезапуска. Если после нового входа проблема возвращается, это уже вопрос устойчивости среды, а не только SwiftUI-кода.

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

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

Если текущий Mac подходит для долгой локальной работы, имеет физические интерфейсы, предсказуемые права и постоянно используется одной командой, покупка и самостоятельное обслуживание могут быть разумнее аренды. Но отдельная машина, используемая только для сборки и Preview, создаёт расходы на оборудование, дисковое пространство, обновления, постоянное питание и самостоятельное восстановление среды. Облачный вариант без полноценной macOS-сессии, в свою очередь, не всегда даёт нужную совместимость с Xcode и Simulator.

Когда требуется временный стенд, параллельная рабочая среда или Mac, который можно заново проверить с независимыми правами, аренда VNCMac позволяет оценить рабочий процесс до долгого обязательства. Рациональный критерий — не обещание, что Canvas никогда не ошибётся, а успешная приёмка именно реального SwiftUI-проекта после входа, перезапуска Xcode и повторного запуска runtime.