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?
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.
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.
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...
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) */
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With