Lea esta respuesta si el mensaje de error hace referencia a archivos de Core Data
Sinopsis: es posible que tenga archivos de clase de objeto administrado Core Data generados automáticamente y manualmente.
Esta respuesta se aplica si la primera línea del error se refiere a un archivo Foo + CoreDataProperties.o o Foo + CoreDataClass.o . Ejemplo:
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
La causa raíz se puede ver al expandir la sección Compilar archivos de origen Swift de la Transcripción de compilación. Por ejemplo:
<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'
El primer archivo mencionado es un archivo fuente en el directorio de su proyecto, que alguien generó seleccionando su modelo de datos en el Navegador de proyectos y haciendo clic en el menú Editor > Crear subclase de objeto administrado . Esta característica se agregó en Xcode 7 más o menos.
El segundo archivo es un archivo con el mismo nombre pero que está enterrado en Xcode DerivedData
. Xcode genera este archivo automáticamente durante cada compilación si el .xcdatamodeld
archivo del modelo de datos ( ) se incluye en la fase de compilación de fuentes de compilación del objetivo . Esta característica se agregó en Xcode 9 más o menos. Cero, se generan uno o dos archivos para cada entidad / clase, dependiendo de la configuración de la ventana emergente Codegen . Esa ventana emergente está en el Inspector del modelo de datos cuando selecciona una entidad mientras edita su modelo de datos ...
Las configuraciones son:
- Manual / Ninguno No se generan archivos
- Categoría / Extensión Un archivo, Foo + CoreDataProperties.m o .swift genera , que contiene una categoría Objective-C o una extensión Swift.
- Definición de clase Se genera el mismo archivo de Categoría / Extensión, y además se genera un Foo + CoreDataClass.m o .swift , que contiene la declaración y definición de clase.
Como puede ver, el problema ocurre cuando un desarrollador (como yo) que está acostumbrado al Xcode más antiguo comienza un proyecto en un Xcode más nuevo. Creemos que necesitamos usar el elemento de menú Crear subclase de objeto administrado , lo que hacemos, para crear los archivos que podemos ver en el Navegador de proyectos sin darnos cuenta de que nuestra configuración en la ventana emergente Codegen está causando que Xcode cree archivos duplicados, lo que Apple "inteligentemente" no se muestra en el Navegador de proyectos, porque no confían en los desarrolladores para leer y prestar atención al comentario en el encabezado // Este archivo se generó automáticamente y no debe editarse.
Solución 1 - Use la forma más antigua
Puede deshabilitar todos los Codegen automáticos para un modelo de datos con solo una configuración:
- Abra el problema Fases de compilación del objetivo (en Project Navigator , seleccione el proyecto, luego en la lista de OBJETIVOS que aparece, seleccione el objetivo del problema, luego la pestaña Fases de compilación ).
- Expanda la entrada Compilar orígenes y busque el modelo de datos del problema (
.xcdatamodeld
archivo).
- Eliminarlo de la lista de compilación
- Asegúrese de que el modelo de datos esté incluido en la lista Copiar recursos del paquete .
Solución 2 - Core Data Magic para principiantes
Aquí, entras en el camino más nuevo.
- Deje su modelo de datos como está en las fuentes de compilación .
- En cada Inspector de entidad en su modelo de datos, establezca Codegen en Definición de clase .
- En el Navegador de proyectos, elimine y elimine los archivos Foo + CoreDataClass y cambie el nombre de cualquier archivo Foo + CoreDataProperties.m o .swift a algo como Foo + MyProperties .
- En cada archivo Foo + MyProperties.m o .swift , si hay propiedades generadas por Xcode, elimine estas propiedades porque estarán en los archivos ocultos creados por Codegen .
Con esta solución, sus definiciones de clase se generan automáticamente a partir del modelo de datos en cada compilación. Ni siquiera puedes verlos. Es Core Data Magic , agradable y simple para principiantes.
Solución 3: para la mayoría de las aplicaciones del mundo real
Pero la Solución 2 no es buena si realmente desea agregar propiedades no administradas. (Objective-C no permite agregar propiedades en categorías, y Swift no permite agregar propiedades almacenadas en extensiones). Por lo tanto, en la mayoría de las aplicaciones del mundo real, es probable que desee ir a la mitad entre las soluciones 1 y 2 ...
- Deje su modelo de datos en la lista de fuentes de compilación
- En cada Inspector de entidad en su modelo de datos, establezca Codegen en Categoría / Extensión .
- En el Navegador de proyectos, elimine y elimine los archivos Foo + CoreDataClass.m o .swift y, para reducir la confusión futura, cambie el nombre de los archivos Foo + CoreDataProperties.m o .swift a quizás solo Foo.m o .swift .
- Asegúrese de que cada archivo Foo.m o .swift contenga la definición de clase, a la que puede agregar sus propias propiedades no administradas.
(Agradecimientos a la respuesta de Positron. Mi respuesta aquí explica por qué funciona la respuesta de Positron (mi Solución 1), y agrega la Solución 2 y la Solución 3.)