Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Core Data Model doesn't appear to be reflected in app

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.

like image 506
jjatie Avatar asked Jun 22 '16 04:06

jjatie


3 Answers

Correcting the NSPersistentContainer name in AppDelegate worked for me.

let container = NSPersistentContainer(name: "sampleDataModel")
like image 90
Alvin George Avatar answered Oct 05 '22 04:10

Alvin George


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

like image 14
cargath Avatar answered Oct 23 '22 02:10

cargath


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 {
}
like image 1
Chris Garrett Avatar answered Oct 23 '22 00:10

Chris Garrett