Прочтите этот ответ, если сообщение об ошибке ссылается на файлы Core Data
Сводка: у вас могут быть как автоматически сгенерированные, так и сгенерированные вручную файлы классов управляемых объектов Core Data.
Этот ответ применяется, если первая строка ошибки относится к файлу Foo + CoreDataProperties.o или Foo + CoreDataClass.o . Пример:
error: Multiple commands produce '/Users/me/Library/Developer/Xcode/DerivedData/MyApp-uebslaqdwgldkjemijpdqmizgyzc/Build/Intermediates.noindex/ MyApp /Debug-iphonesimulator/ MyApp.build/Objects-normal/x86_64/Foo+CoreDataProperties.o':
1) Target ' MyApp ' (project ' MyApp ') has compile command for Swift source files
2) Target ' MyApp ' (project ' MyApp ') has compile command for Swift source files
Первопричину можно увидеть, развернув раздел Compile Swift Source Files в Build Transcript. Например:
<unknown>:0: error: filename "Address+CoreDataClass.swift" used twice: '/Users/myUserName/Projects/Jnky/Foo+CoreDataProperties' and '/Users/jk/myUserName/Developer/Xcode/DerivedData/MyApp-uebslaqdwgldkjemijpdqmizgyzc/Build/Intermediates.noindex/MyApp.build/Debug/MyApp.build/DerivedSources/CoreDataGenerated/Jnky/Foo+CoreDataProperties.swift'
Первый упомянутый файл - это исходный файл в каталоге вашего проекта, который кто-то сгенерировал, выбрав вашу модель данных в Навигаторе проектов и щелкнув в меню « Редактор» > « Создать подкласс управляемых объектов». . Эта функция была добавлена в Xcode 7 или около того.
Второй файл - это файл с тем же именем, но он похоронен в Xcode DerivedData
. Этот файл автоматически генерируется XCode во время каждой сборки, если .xcdatamodeld
файл модели данных ( ) включен в целевую фазу сборки Источники компиляции . Эта функция была добавлена в Xcode 9 или около того. Ноль, один или два файла генерируются для каждого объекта / класса, в зависимости от настройки всплывающего окна Codegen . Это всплывающее окно находится в инспекторе моделей данных, когда вы выбираете объект при редактировании модели данных ...
Настройки:
- Ручной / Нет Файлы не создаются
- Категория / расширение Создается один файл Foo + CoreDataProperties.m или .swift , содержащий категорию Objective-C или расширение Swift.
- Определение класса Генерируется тот же файл категории / расширения, и, кроме того, генерируется Foo + CoreDataClass.m или .swift , содержащий объявление и определение класса.
Итак, вы видите, что проблема возникает, когда разработчик (как я), который привык к старому Xcode, начинает проект в более новом Xcode. Мы считаем, что нам нужно использовать пункт меню « Создать подкласс управляемых объектов» , который мы делаем, чтобы создавать файлы, которые мы можем видеть в Навигаторе проекта, не осознавая, что наши настройки во всплывающем окне Codegen заставляют Xcode создавать дубликаты файлов, которые Apple «Умно» не отображается в Навигаторе проектов, потому что они не доверяют разработчикам читать и учитывать комментарий в заголовке // Этот файл создан автоматически и не должен редактироваться.
Решение 1 - использовать старый путь
Вы можете отключить все автоматические Codegen для модели данных только с одним параметром:
- Откройте задачу Этапы сборки цели (в Навигаторе проектов выберите проект, затем в появившемся списке ЦЕЛЕЙ выберите цель задачи, затем вкладку Этапы сборки ).
- Разверните запись Compile Sources и найдите модель данных о проблеме (
.xcdatamodeld
файл).
- Удалить его из списка компиляции
- Убедитесь, что модель данных включена в список ресурсов пакета копирования .
Решение 2 - Волшебство основных данных для начинающих
Здесь вы идете олл-ин на новый путь.
- Оставьте вашу модель данных такой же, как в этих источниках компиляции .
- В каждом Entity Inspector в вашей модели данных установите Codegen на Определение класса .
- В Навигаторе проектов удалите и удалите все файлы Foo + CoreDataClass и переименуйте любые файлы Foo + CoreDataProperties.m или .swift во что-то вроде Foo + MyProperties .
- В каждом файле Foo + MyProperties.m или .swift , если есть свойства, сгенерированные Xcode, удалите эти свойства, поскольку они будут в скрытых файлах, созданных Codegen .
С этим решением ваши определения классов генерируются автоматически из модели данных каждой сборки. Вы даже не можете их видеть. Это Core Data Magic , приятное и простое для начинающих.
Решение 3 - Для большинства реальных приложений
Но решение 2 бесполезно, если вы действительно хотите добавить неуправляемые свойства. (Objective-C не позволяет добавлять свойства в категориях, а Swift не позволяет добавлять сохраненные свойства в расширениях.) Поэтому в большинстве реальных приложений вы, вероятно, захотите пойти на полпути между решениями 1 и 2…
- Оставьте свою модель данных в списке источников компиляции
- В каждом Entity Inspector в вашей модели данных установите Codegen на Category / Extension .
- В Навигаторе проектов удалите и удалите любые файлы Foo + CoreDataClass.m или .swift и, чтобы уменьшить путаницу в будущем, переименуйте любые файлы Foo + CoreDataProperties.m или .swift, возможно, просто Foo.m или .swift .
- Убедитесь, что каждый файл Foo.m или .swift содержит определение класса, к которому вы можете добавить свои собственные неуправляемые свойства.
(Благодарность ответу Позитрона. Мой ответ здесь объясняет, почему ответ Позитрона (мое Решение 1) работает, и добавляет Решение 2 и Решение 3.)