Duplikuję istniejącą aplikację Objective-C TV Show do nowej wersji Swift przy użyciu Xcode 6.1 i mam pewne problemy z CoreData.
Stworzyłem model 4 jednostek, utworzyłem ich podklasę NSManagedObject (w Swift), a wszystkie pliki mają ustawione odpowiednie cele aplikacji (dla „Źródła kompilacji”).
Nadal pojawia się ten błąd za każdym razem, gdy próbuję wstawić nową jednostkę:
CoreData: ostrzeżenie: nie można załadować klasy o nazwie „Programy” dla jednostki „Programy”. Nie znaleziono klasy, zamiast tego użyto domyślnego NSManagedObject.
Kilka uwag:
Podczas zapisywania do danych podstawowych używam sposobu kontekstu rodzic-dziecko, aby umożliwić wątkowanie w tle. Robię to, konfigurując ManagedObjectContext przy użyciu:
lazy var managedObjectContext: NSManagedObjectContext? = {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
let coordinator = self.persistentStoreCoordinator
if coordinator == nil {
return nil
}
var managedObjectContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.MainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()
i zapisując dane za pomocą:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
var context = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType)
context.parentContext = self.managedObjectContext!
...rest of core data saving code here...
})
źródło
@objc(MyClass)
Ale dla tych, którzy używają
@objc(myEntity)
w Swift (jak ja), możesz użyć tego innego rozwiązania, które działa płynnie.W xcdatamodel poprawna klasa w. Powinna wyglądać następująco:
Proszę bardzo.
Module.Class
jest wzorcem dla CoreData w Swift i XCode 6. Będziesz również potrzebował tej samej procedury podczas używania klasy Custom Policy w Model Policy lub innych elementach CoreData. Uwaga: na obrazku nazwa i klasa powinny mieć postać Car i MyAppName.Car (lub jakakolwiek inna nazwa Twojej jednostki). TutajUser
jest literówka.źródło
Car
dla obu pól załatwiło sprawę.Używając Xcode 7 i wyłącznie Swift, musiałem usunąć
@objc(MyClass)
z mojej automatycznie wygenerowanejNSManagedObject
podklasy (wygenerowanej z Editor> Create NSManagedObject Subclass...).źródło
W Xcode 7 beta 2 (i wierzę 1), w konfiguracji modelu nowy obiekt zarządzany typu
File
jest ustawiony na Module,Current Product Module
a klasa obiektu jest wyświetlana w konfiguracji jako.File
.Usunięcie ustawienia modułu tak, aby był pusty, lub usunięcie kropki, aby nazwa klasy w konfiguracji była po prostu
File
akcjami równoważnymi, ponieważ każda z nich powoduje inną zmianę. Zapisanie tej konfiguracji usunie opisany błąd.źródło
W Xcode 6.1.1 nie musisz dodawać atrybutu @objc, ponieważ jednostka podstawowa jest podzbiorem klasy objc (NSManagedObject) (zobacz Zgodność typu Swift . W CoreData wymagana jest pełna nazwa Module.Class. Pamiętaj, że moduł nazwa jest ustawiona w Ustawienia kompilacji -> Pakowanie -> Nazwa modułu produktu.Domyślnie jest to ustawione na $ (PRODUCT_NAME: c99extidentifier), który będzie nazwą celu .
źródło
my-product
wmy_product
i to miało znaczenie dla Core Data.W przypadku wersji xCode 7 i Swift 2.0 nie trzeba dodawać @objc (NameOfClass), wystarczy zmienić ustawienia encji na karcie „Pokaż inspektora modelu danych”, jak poniżej -
Nazwa - „Nazwa Twojej jednostki”
Klasa - „Nazwa Twojej jednostki”
Moduł - „Bieżący moduł produktu”
Kod dla pliku klasy jednostki będzie wyglądał następująco (w moim kodzie Entity is Family) -
Ten przykład działa dobrze w mojej aplikacji z xCode 7.0 + Swift 2.0
źródło
Nie zapomnij zastąpić
PRODUCT_MODULE_NAME
nazwą modułu produktu.Po utworzeniu nowej encji musisz przejść do Inspektora modelu danych (ostatnia karta) i zastąpić
PRODUCT_MODULE_NAME
nazwą swojego modułu, w przeciwnym razie spowoduje toclass not found
błąd podczas tworzenia stałego koordynatora magazynu.źródło
Musisz także użyć (przynajmniej z Xcode 6.3.2) Module.Class podczas obsady, na przykład: Zakładając, że twój moduł (tj. Nazwa produktu) to Food, a twoja klasa to Fruit
Podsumować:
źródło
Napotkałem również podobny problem, wykonaj następujące kroki, aby rozwiązać :
źródło
Zmiana nazwy klasy jednostki w edytorze modelu danych tak, aby odpowiadała danej klasie i dodanie
@objc(NameOfClass)
do pliku każdego NSManagedObject tuż nad deklaracją klasy rozwiązało ten problem podczas testów jednostkowych.źródło
To, co zadziałało dla mnie (Xcode 7.4, Swift), to zmiana nazwy klasy na
<my actual class name>.<entity name>
w Inspektorze jednostek, w polu „Klasa”.Mój inicjator podklasy obiektu zarządzanego wygląda następująco:
źródło
Dla Xcode 11.5: jeśli właściwość Codegen to Definicja klasy i jeśli nie otrzymujesz sugestii dla jednostki utworzonej w xcdatamodel. Spróbuj zamknąć Xcode i ponownie otworzyć projekt. Mi to pasuje. Ta odpowiedź jest tylko wtedy, gdy nie otrzymujesz sugestii, ale jeśli plik nie zostanie wygenerowany, wypróbuj dowolną z powyższych odpowiedzi.
źródło