Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting an NSManagedObject relationship in Swift

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?

like image 454
Andrew Ebling Avatar asked Jun 10 '14 16:06

Andrew Ebling


People also ask

What is relationship in Core Data?

A relationship's delete rule specifies how changes propagate across relationships when Core Data deletes a source instance. Select No Action to delete the source object instance, but leave references to it in any destination object instances, which you update manually.

How do I create a subclass in NSManagedObject?

From the Xcode menu bar, choose Editor > Create NSManagedObject Subclass. Select your data model, then the appropriate entity, and choose where to save the files. Xcode places both class and properties files into your project.


2 Answers

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...

like image 114
lehn0058 Avatar answered Sep 27 '22 21:09

lehn0058


Yeah that's not going to work anymore, Swift cannot generate accessors at runtime in this way, it would break the type system.

What you have to do is use the key paths:

var manyRelation = myObject.valueForKeyPath("subObjects") as NSMutableSet manyRelation.addObject(subObject) /* (Not tested) */ 
like image 31
iluvcapra Avatar answered Sep 27 '22 20:09

iluvcapra