Generating Swift models from Core Data entities
According to Apple's video regarding What's new In CoreData frame: 38mins (WWDC2014 Session 225), in inspector's Data Model, prefix the class name with the project name. Like projectName.Doctor
I've tried this but what will happen is that the generated managed object class becomes: projectName.swift instead of Doctor.swift. Even the class declaration becomes class projectName: ManagedObject
Solution:
In Data model inspector, just specify the Name & Class of your object to what name you want, example: Doctor
After you generated an object model and selecting Swift, this will create a file (Doctor.swift).
Now, when inserting new records in Core Data, you might an experience error "Class not found, using default NSManagedObject instead" even if you cast the newly inserted object to a correct object name.
To solve this, you just need to add @objc(class name) above the class declaration. See sample below.
import Foundation
import CoreData
@objc(Doctor)
class Doctor: NSManagedObject {
@NSManaged var name: String
}
Then:
let doctorManagedObject = NSEntityDescription.insertNewObjectForEntityForName("Doctor", inManagedObjectContext: context) as Doctor
doctorManagedObject.name = "John" // you can now use dot syntax instead of setValue
Save context to commit insert.
I tested @NSManaged, it didn't work. :( . But mixed models files(.h) generated by xcdatamodel, it succeed. please read the doc and code in https://github.com/iascchen/SwiftCoreDataSimpleDemo
Lets have a look on the Objective-C way:
Person.h (Header-File)
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@interface Person : NSManagedObject
@property (nonatomic, retain) NSString *name;
@end
Person.m (Implementation-File)
#import "Person.h"
@implementation Person
@dynamic name;
@end
Swift
The documentation already included in Xcode6-Beta says:
Core Data provides the underlying storage and implementation of properties in subclasses of the NSManagedObject class. Add the @NSManaged attribute before each property definition in your managed object subclass that corresponds to an attribute or relationship in your Core Data model. Like the @dynamic attribute in Objective-C, the @NSManaged attribute informs the Swift compiler that the storage and implementation of a property will be provided at runtime. However, unlike @dynamic, the @NSManaged attribute is available only for Core Data support.
So that is how I would rewrite the above example for Swift (not tested):
Person.swift
import CoreData
class Person: NSManagedObject {
@NSManaged var name : NSString
}
And according to your question I think the subclass-generation-feature might be not included in Xcode6 yet. Did you made sure that you have chosen "Swift" as programming language when you were creating the Cocoa-Project in Xcode?
You can get Swift model back using NSEntityDescription.insertNewObjectForEntityForName
but you must edit your core data model file and not use Person
as a Class Entity but <ProjectName>.Person
else it returns NSManagedObject
...
Using println()
you won't see Person
instance but something like <_TtC5ProjectName4Person: 0xc9ad5f0>
but calling methods on this will prove it's a Person
instance for real. I guess it's just the way for Swift to generate unique class names, not conflict and CoreData methods show this internal mechanism.
The Apple documentation says:
Swift classes are namespaced—they’re scoped to the module (typically, the project) they are compiled in. To use a Swift subclass of the NSManagedObject class with your Core Data model, prefix the class name in the Class field in the model entity inspector with the name of your module.