Setting an NSManagedObject relationship in Swift

Andrew Ebling picture Andrew Ebling · Jun 10, 2014 · Viewed 22.5k times · Source

How does one add an object to a relationship property in an NSManagedObject subclass in Swift?

In Objective-C, when you generate an NSManagedObject subclass in Xcode from the data model, there's an automatically generated class extension which contains declarations like:

@interface MyManagedObject (CoreDataGeneratedAccessors)

     - (void)addMySubObject: (MyRelationshipObject *)value;
     - (void)addMySubObjects: (NSSet *)values;

@end

However Xcode currently lacks this class generation capability for Swift classes.

If I try and call equivalent methods directly on the Swift object:

myObject.addSubObject(subObject)

...I get a compiler error on the method call, because these generated accessors are not visible.

I've declared the relationship property as @NSManaged, as described in the documentation.

Or do I have to revert to Objective-C objects for data models with relationships?

Answer

lehn0058 picture lehn0058 · Nov 6, 2015

As of Xcode 7 and Swift 2.0 (see release note #17583057), you are able to just add the following definitions to the generated extension file:

extension PersonModel {
    // This is what got generated by core data
    @NSManaged var name: String?
    @NSManaged var hairColor: NSNumber?
    @NSManaged var parents: NSSet?

    // This is what I manually added
    @NSManaged func addParentsObject(value: ParentModel)
    @NSManaged func removeParentsObject(value: ParentModel)
    @NSManaged func addParents(value: Set<ParentModel>)
    @NSManaged func removeParents(value: Set<ParentModel>)
}

This works because

The NSManaged attribute can be used with methods as well as properties, for access to Core Data’s automatically generated Key-Value-Coding-compliant to-many accessors.

Adding this definition will allow you to add items to your collections. Not sure why these aren't just generated automatically...