Leggere questa risposta se il messaggio di errore fa riferimento a file di dati principali
Sinossi: Potresti avere sia file di classe di oggetti gestiti generati automaticamente che generati manualmente.
Questa risposta si applica se la prima riga dell'errore si riferisce a un file Foo + CoreDataProperties.o o Foo + CoreDataClass.o . Esempio:
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 principale può essere vista espandendo la sezione Compile Swift Source Files della Build Transcript. Per esempio:
<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'
Il primo file menzionato è un file di origine nella directory del progetto, che qualcuno ha generato selezionando il modello di dati nel Navigatore progetto e facendo clic nel menu Editor > Crea sottoclasse oggetto gestito . Questa funzione è stata aggiunta in Xcode 7 o giù di lì.
Il secondo file è un file con lo stesso nome ma che è sepolto in Xcode DerivedData
. Questo file viene generato automaticamente da Xcode durante ogni build se il file del modello di dati ( .xcdatamodeld
) è incluso nella fase di compilazione Sorgenti di compilazione del target . Questa funzione è stata aggiunta in Xcode 9 o giù di lì. Zero, vengono generati uno o due file per ogni entità / classe, a seconda dell'impostazione del popup Codegen . Tale popup si trova in Impostazioni modello dati quando selezioni un'entità durante la modifica del modello di dati ...
Le impostazioni sono:
- Manuale / Nessuno Nessun file generato
- Categoria / Estensione Un file, Foo + CoreDataProperties.m o .swift Viene generato , contenente una categoria Objective-C o estensione Swift.
- Definizione della classe Viene generato lo stesso file di categoria / estensione e inoltre viene generato un Foo + CoreDataClass.m o .swift , contenente la dichiarazione e la definizione della classe.
Quindi vedi che il problema si verifica quando uno sviluppatore (come me) abituato al vecchio Xcode inizia un progetto in un nuovo Xcode. Riteniamo di dover utilizzare la voce di menu Crea sottoclasse di oggetti gestiti , che facciamo, per creare i file che possiamo vedere nel Navigatore progetto senza renderci conto che le nostre impostazioni nel popup Codegen stanno facendo sì che Xcode crei file duplicati, che Apple "abilmente" non viene visualizzato nel Navigatore progetto, perché non si fidano degli sviluppatori di leggere ed ascoltare il commento nell'intestazione // Questo file è stato generato automaticamente e non deve essere modificato.
Soluzione 1: utilizzare il modo precedente
Puoi disabilitare tutti i Codegen automatici per un modello di dati con una sola impostazione:
- Apri il problema Fasi di costruzione del target (in Project Navigator , seleziona il progetto, quindi nell'elenco di TARGET che appare, seleziona il target del problema, quindi fai clic su Crea fasi ).
- Espandere la voce Compila origini e trovare il modello di dati del problema (
.xcdatamodeld
file).
- Eliminalo dall'elenco di compilazione
- Assicurarsi che il modello dati sia incluso nell'elenco Risorse pacchetto copia .
Soluzione 2 - Core Data Magic per principianti
Qui, vai all in nel modo più recente.
- Lascia il tuo modello di dati come è nelle fonti di compilazione .
- In ogni ispettore entità nel modello dati, imposta Codegen su Definizione classe .
- Nel Project Navigator, elimina e cancella tutti i file Foo + CoreDataClass e rinomina i file Foo + CoreDataProperties.m o .swift in qualcosa come Foo + MyProperties .
- In ogni file Foo + MyProperties.m o .swift , se sono presenti proprietà generate da Xcode, eliminare queste proprietà perché si troveranno nei file nascosti creati da Codegen .
Con questa soluzione, le definizioni delle classi vengono generate automaticamente dal modello di dati su ogni build. Non puoi nemmeno vederli. È Core Data Magic , piacevole e semplice per i principianti.
Soluzione 3 - Per la maggior parte delle app del mondo reale
Ma la soluzione 2 non va bene se vuoi davvero aggiungere proprietà non gestite. (Objective-C non consente l'aggiunta di proprietà nelle categorie e Swift non consente l'aggiunta di proprietà memorizzate nelle estensioni.) Quindi nella maggior parte delle app del mondo reale, probabilmente vorrai andare a metà strada tra le soluzioni 1 e 2 ...
- Lascia il tuo modello di dati nell'elenco delle fonti di compilazione
- In ogni ispettore entità nel modello dati, imposta Codegen su Categoria / Estensione .
- Nel Project Navigator, eliminare e eliminare qualsiasi file Foo + CoreDataClass.m o .swift e, per ridurre la confusione futura, rinominare qualsiasi file Foo + CoreDataProperties.m o .swift in forse solo Foo.m o .swift .
- Assicurarsi che ogni file Foo.m o .swift contenga la definizione della classe, alla quale è possibile aggiungere le proprie proprietà non gestite.
(Ringraziamenti alla risposta di Positron. La mia risposta qui spiega perché la risposta di Positron (la mia soluzione 1) funziona e aggiunge la soluzione 2 e la soluzione 3.)