In CoreData, I have defined an unordered to-many relationship from Node
to Tag
. I've created an Swift entity like this:
import CoreData
class Node : NSManagedObject {
@NSManaged var tags : Array<Tag>
}
Now I want to add a Tag
to an instance of Node
, like this:
var node = NSEntityDescription.insertNewObjectForEntityForName("Node", inManagedObjectContext: managedObjectContext) as Node
node.tags.append(tag)
However, this fails with the following error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unacceptable type of value for to-many relationship: property = "tags"; desired type = NSSet; given type = _TtCSs22ContiguousArrayStorage000000000B3440D4; value = ( "<_TtC8MotorNav3Tag: 0xb3437b0> (entity: Tag; id: 0xb343800 ; data: {...})" ).'
What is the correct type for to-many relationships?
Actually you can just define:
And use the
insert
andremove
methods of theSet
directly.As of Xcode 7 and Swift 2.0, the release note 17583057 states:
So you just have to declare the following methods and CoreData will take care of the rest:
Building on @Keenle's answer, if you want to be cheeky and concise and be able to say
one can wrap the call to self.mutableSetValueForKey:
To be able to work with one-to-many relationship in Swift you need to define property as:
If you try to use
NSMutableSet
changes will not be saved in CoreData. And of course it is recommended to define reverse link inNode
:But still Swift cannot generate dynamic accessors in runtime, so we need to define them manually. It is very convenient to define them in class
extension
and put inEntity+CoreData.swift
file. Bellow is content ofNode+CoreData.swift
file:Usage:
Important: To make it all work you should verify that class names of entities in you CoreData model includes your module name. E.g.
MyProjectName.Node