10

I'm having difficulty with Core Data in Xcode 8 beta 1. Old apps will compile and run fine, but all new apps compile and run fine until trying to insert a new NSManagedObject.

Initially I thought it had something to do with incorrectly deleting an old xcdatamodel and remaking another, but after making a brand new app and making a simple Entity "A", I am not able to create an object of class A at runtime.

I have tried using let a = A(context: myMOC) which returns the error:

An NSManagedObject of class 'MyApp.A' must have a valid NSEntityDescription.

Trying the old let a = NSEntityDescription.insertNewObject(forEntityName: "A", into: context) as! A returns the error:

Could not cast value of type 'NSManagedObject_A_' (0x7fd114626f80) to 'MyApp.A' (0x10d2fdf28).

I have checked my xcdatamodel a dozen times to ensure I have spelt everything correctly, and have created a new project to test to make sure I haven't made any errors in setting up CD. Thoughts?

UPDATE: The xcdatamodel package contents are this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="11147.23" systemVersion="16A201w" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
    <entity name="Coordinate" syncable="YES" codeGenerationType="class">
        <attribute name="latitude" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES" syncable="YES"/>
        <attribute name="longitude" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES" syncable="YES"/>
        <relationship name="route" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Route" inverseName="coordinates" inverseEntity="Route" syncable="YES"/>
    </entity>
    <entity name="Route" syncable="YES" codeGenerationType="class">
        <attribute name="uuid" optional="YES" attributeType="String" syncable="YES"/>
        <relationship name="coordinates" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="Coordinate" inverseName="route" inverseEntity="Coordinate" syncable="YES"/>
    </entity>
    <elements>
        <element name="Route" positionX="-45" positionY="0" width="128" height="75"/>
        <element name="Coordinate" positionX="-18" positionY="27" width="128" height="90"/>
    </elements>
</model>

UPDATE 2: Printing the managedObjectModel's entities, shows that the correct model is being loaded. Still I can't get an NSManagedObject to initialize in any new project.

jjatie
  • 5,152
  • 5
  • 34
  • 56
  • The second error you listed is what I'd expect if the custom class name/module aren't filled out correctly in the data model. Have you verified they are correct? – Charles A. Jun 22 '16 at 04:58
  • I have verified multiple times. I've tested every entity I have and get the same errors. – jjatie Jun 22 '16 at 05:00
  • Please add the contents of the XML of your data model to your Q. You find it inside the xcdatamodel package. Alternatively add a screen shot of the model editor. – Amin Negm-Awad Jun 22 '16 at 05:24
  • Hi. Did you see this similar question that was posted earlier? It may help you. http://stackoverflow.com/questions/37956720/how-to-create-managedobjectcontext-using-swift-3-in-xcode-8/37959165#37959165 – Edison Jun 22 '16 at 05:39
  • @tymac I did see this. You do not need to create a moc, as the persistentContainer now holds one (covered in WWDC 2016 What's New in Core Data). I do inject this the standard way and verified that I am getting the context passed down to the view controller. – jjatie Jun 22 '16 at 14:25
  • @AminNegm-Awad I looked in package contents, but there is no xml file – jjatie Jun 22 '16 at 14:27
  • Likely the contents is the XML file. – Amin Negm-Awad Jun 22 '16 at 15:57
  • 2
    I have the same problem, in both Xcode 8 beta 1 and beta 2. Seems to be related to generated classes. – cargath Jul 11 '16 at 12:01

3 Answers3

14

I finally figured it out:

In Xcode 7 you would have to enter the class name and, in Swift, set the module to "Current Project Module". I assumed that wouldn't be necessary anymore in Xcode 8, since it automatically generates the source files. You do have to manually set the class name to the name of the generated class though, to make Xcode generate the @objc(ClassName) (i have no idea why it needs that annotation - manually created classes for CoreData entities work without it for me). Also you have to NOT manually set the module, because otherwise Xcode can't find the generated class anymore.

enter image description here

cargath
  • 832
  • 8
  • 18
  • Thanks! I'm away for a couple days. I'll test it out when I get home and accept your answer. – jjatie Jul 11 '16 at 12:40
  • 5
    I was having the same issue `*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'An NSManagedObject of class 'MyAp.MyClass' must have a valid NSEntityDescription.'` I had to add `@objc(MyClass)` to the top of my manage object class. – Chéyo Oct 11 '16 at 19:03
  • Same worked for me as masters3d. You put @objc(MyClass) on the line before you write class MyClass: NSManagedObject { // ... } and the problem went away – horseshoe7 Nov 18 '16 at 20:49
  • Hey, I learnt somewhere that unless you are using different modules, let's say in a workspace you do not need to change the name of the module to "Current Product Module" (and you can let it be Global...). I was having the same problem as mentioned in the question, but as soon as I changed the module to "Current..." it started working fine. I was wondering why would this be, any idea? – Manganese Nov 26 '17 at 05:18
1

I was having the same error. In my case I needed to expose the Swift class to the ObjectiveC runtime. To do this, add @objc(ModelClass) before the Swift class declaration, as follows:

@objc(Player)
class Player: NSManagedObject {
}
Chris Garrett
  • 4,824
  • 1
  • 34
  • 49
1

Correcting the NSPersistentContainer name in AppDelegate worked for me.

let container = NSPersistentContainer(name: "sampleDataModel")
Alvin George
  • 14,148
  • 92
  • 64