Przeczytaj tę odpowiedź, jeśli komunikat o błędzie odwołuje się do plików danych podstawowych
Streszczenie: Możesz mieć zarówno generowane automatycznie, jak i ręcznie generowane pliki klas obiektów zarządzanych przez Core Data.
Ta odpowiedź ma zastosowanie, jeśli pierwszy wiersz błędu odnosi się do pliku Foo + CoreDataProperties.o lub Foo + CoreDataClass.o . Przykład:
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
Główną przyczynę można zobaczyć, rozwijając sekcję Kompiluj szybkie pliki źródłowe transkrypcji kompilacji. Na przykład:
<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'
Pierwszy wspomniany plik to plik źródłowy w katalogu projektu, który ktoś wygenerował, wybierając model danych w Nawigatorze projektu i klikając w menu Edytor > Utwórz podklasę obiektu zarządzanego . Ta funkcja została dodana w Xcode 7 lub więcej.
Drugi plik jest plikiem o tej samej nazwie, ale jest zakopany w Xcode DerivedData
. Plik ten jest generowany automatycznie przez Xcode podczas każdej kompilacji, jeśli .xcdatamodeld
plik modelu danych ( ) jest zawarty w fazie kompilacji źródeł kompilacji celu. Ta funkcja została dodana w Xcode 9 lub więcej. Zero, jeden lub dwa pliki są generowane dla każdej jednostki / klasy, w zależności od ustawienia wyskakującego okienka Codegen . To okienko wyskakujące znajduje się w Inspektorze modelu danych po wybraniu elementu podczas edycji modelu danych…
Ustawienia są następujące:
- Ręcznie / Brak Żadne pliki nie są generowane
- Kategoria / rozszerzenie Generowany jest jeden plik, Foo + CoreDataProperties.m lub .swift , zawierający kategorię Objective-C lub rozszerzenie Swift.
- Definicja klasy Generowany jest ten sam plik kategorii / rozszerzenia, a ponadto generowany jest Foo + CoreDataClass.m lub .swift , zawierający deklarację klasy i definicję.
Widzisz więc, że problem występuje, gdy programista (jak ja) przyzwyczajony do starszego Xcode rozpoczyna projekt w nowszym Xcode. Uważamy, że musimy użyć elementu menu Utwórz podklasę obiektów zarządzanych , co robimy, aby utworzyć pliki, które widzimy w Nawigatorze projektu, nie zdając sobie sprawy, że nasze ustawienia w wyskakującym oknie Codegen powodują, że Xcode tworzy duplikaty plików, które Apple „sprytnie” nie pojawia się w Nawigatorze projektu, ponieważ nie ufają programistom, że przeczytają i zważą na komentarz w nagłówku // Ten plik został wygenerowany automatycznie i nie należy go edytować.
Rozwiązanie 1 - Użyj starszej drogi
Możesz wyłączyć wszystkie automatyczne Codegen dla modelu danych za pomocą tylko jednego ustawienia:
- Otwórz problem Fazy kompilacji celu (w Nawigatorze projektów wybierz projekt, a następnie na wyświetlonej liście CELE , wybierz cel problemu, a następnie kartę Fazy kompilacji ).
- Rozwiń pozycję Kompiluj źródła i znajdź problematyczny model danych (
.xcdatamodeld
plik).
- Usuń go z listy kompilacji
- Upewnij się, że model danych znajduje się na liście zasobów pakietu kopii .
Rozwiązanie 2 - Podstawowa magia danych dla początkujących
Tutaj wchodzisz all-in na nowszą drogę.
- Pozostaw model danych taki, jaki jest w tym źródle kompilacji .
- W każdym Inspektorze jednostek w modelu danych ustaw Codegen na Definicja klasy .
- W Nawigatorze projektu usuń i usuń wszystkie pliki Foo + CoreDataClass i zmień nazwę dowolnego pliku Foo + CoreDataProperties.m lub .swift na coś takiego jak Foo + MyProperties .
- W każdym pliku Foo + MyProperties.m lub .swift , jeśli istnieją właściwości generowane przez Xcode, usuń te właściwości, ponieważ będą one znajdować się w ukrytych plikach utworzonych przez Codegen .
Dzięki temu rozwiązaniu definicje klas są generowane automatycznie na podstawie modelu danych dla każdej kompilacji. Nawet ich nie widzisz. Jest to Core Data Magic , ładne i proste dla początkujących.
Rozwiązanie 3 - Dla większości aplikacji w świecie rzeczywistym
Ale rozwiązanie 2 nie jest dobre, jeśli naprawdę chcesz dodać właściwości niezarządzane. (Objective-C nie pozwala na dodawanie właściwości w kategoriach, a Swift nie pozwala na dodawanie przechowywanych właściwości w rozszerzeniach). Więc w większości rzeczywistych aplikacji prawdopodobnie chcesz przejść w połowie drogi między Rozwiązaniami 1 i 2…
- Pozostaw swój model danych na liście Kompiluj źródła
- W każdym Inspektorze jednostek w modelu danych ustaw Codegen na Kategoria / Rozszerzenie .
- W Nawigatorze projektu usuń i usuń wszystkie pliki Foo + CoreDataClass.m lub .swift i, aby zmniejszyć przyszłe nieporozumienia, zmień nazwę dowolnego pliku Foo + CoreDataProperties.m lub .swift na być może po prostu Foo.m lub .swift .
- Upewnij się, że każdy plik Foo.m lub .swift zawiera definicję klasy, do której możesz dodać własne niezarządzane właściwości.
(Podziękowania dla odpowiedzi firmy Positron. Moja odpowiedź tutaj wyjaśnia, dlaczego odpowiedź Positron (moje Rozwiązanie 1) działa, i dodaje Rozwiązanie 2 i Rozwiązanie 3)