8

In Swift 2.0, are one-to-many relationships in Core Data still NSOrderedSets?

I cannot seem to be able to cast/downcast appropriately to ever not throw errors.

Does anyone have a simple example of this in Swift 2.0?

Kent
  • 1,705
  • 3
  • 16
  • 26

2 Answers2

3

Only if you flag the relationship with the option "Ordered". If not, then it's a NSSet.

I don't agree with the accepted answer because in Swift 2.0 bridging from NSSet to a Set happens automatically, so if you can subclass the CoreData entity, you can just write:

@NSManaged var oneToManyOfTypeFoo: Set<Foo>

And then adding and removing elements becomes trivial, because you can just use the insert and remove methods from Set.

FranMowinckel
  • 4,233
  • 1
  • 30
  • 26
  • When you've picked the ordered option Xcode automatically adds NSOrderedSet instead of NSSet and you can't use with NSOrderedSet. How to handle the order related operations with Set ? Thanks... – emreoktem May 17 '17 at 12:45
  • 1
    `NSOrderedSet` is a different structure and cannot be cast to `Set`. As I see you have two options: the first one is to stick to `NSOrderedSet` so my answer is irrelevant to you. The other is to deselect the ordered option and use a `Set`. Then you can sort it: `myset.sorted(by:)` – FranMowinckel May 18 '17 at 10:21
1

Unfortunately CoreData with swift is still a huge pain especially with ordered one-many relationships. Yes, it is still NSOrderedSet that is being used by CoreData for to-many relationships. The question is how to add/remove items to this. Xcode has never been able to generate accessors properly for the ordered set so far - even in Objective let alone Swift!!.

There is this thread on saving to-many relations in Swift: How to define CoreData relationship in Swift?

But, alas!, nothing mentioned in this thread ever works in Swift 2.0 world. So what is the workaround for now? I digged into this, and the only way to get this working is generating the sources for entities in question, in Objective C, and not in swift and exporting the headers of them in the bridging header. Also you need to ensure you include an important workaround fix for Xcode to generate proper accessors for ordered set:

https://github.com/CFKevinRef/KCOrderedAccessorFix

You should ensure to call- model.kc_generateOrderedSetAccessors() in your model creation code in AppDelegate to invoke this fix.

Once done, you can now safely start using the generated accessors on your model to add items to a to-many relationship.

I have created a sample project and is in github and hope it helps-

https://github.com/shripada/CoreDataToManyRelationshipInSwift2.0

Community
  • 1
  • 1
Shripada
  • 6,296
  • 1
  • 30
  • 30
  • 1
    Turns out it's gotten simpler in XCode 7 beta 5. Core Data now uses NSSet for one-to-many relationships. Create an NSMutableSet such as "let clientSet: NSMutableSet = []" then add a Core Data object to the set "clientsSet.addobject(aClientObject)" and then put the set into the relationship like "event.clients = clientsSet" and you're done. All I had to do was regenerate my classes that weren't working (like my Event). I was still using some classes generated from Core Data in XCode 7 beta 4 and that was messing me up (Event was using NSOrderedSet rather than NSSet). – Kent Aug 22 '15 at 00:45