0
votes

Using Core Data, I have two entities that have many-to-many relationships. So:

Class A <<---->> Class B

Both relationships are set up as 'ordered' so I can track they're order in a UITableView. That works fine, no problem.

I am about to try and implement iCloud with this Core Data model, and find out that iCloud doesn't support ordered relationships, so I need to reimplement the ordering somehow.

I've done this with another entity that has a one-to-many relationship with no problem, I add an 'order' attribute to the entity and store it's order information there. But with a many-to-many relationship I need an unknown number of order attributes.

I can think of two solutions, neither of which seem ideal to me so maybe I'm missing something;

Option 1. I add an intermediary entity. This entity has a one-to-many relationship with both entities like so:

Class A <<--> Class C <-->> Class B

That means I can have the single order attribute in this helper entity.

Option 2. Instead of an order attribute that stores a single order number, I store a dictionary that I can store as many order numbers as I need, probably with the corresponding object (ID?) as the key and the order number as the value.

I'm not necessarily looking for any code so any thoughts or suggestions would be appreciated.

2
The best way for iCloud sync ... ensembles.ioDogCoffee
Wouldn't those to-many arrows be flipped? It seems like each ordering entity would have one reference to a class A instance and one to a class B instance. Then the A and B entities would have many ordering references..BigBoy1337

2 Answers

1
votes

I think your option 1, employing a "join table" with an order attribute is the most feasible solution for this problem. Indeed, this has been done many times in the past. This is exactly the case for which you would use a join table in Core Data although the framework already gives you many-to-many relationships: if you want to store information about the relationship itself, which is precisely your case. Often these are timestamps, in your case it is a sequence number.

You state: "...solutions, neither of which seem ideal to me". To me, the above seems indeed "ideal". I have used this scheme repeatedly with great performance and maintainability.

The only problem (though it is the same as with a to-one relationship) is that when inserting an item out of sequence you have to update many entities to get the order right. That seems cumbersome and could potentially harm performance. In practice, however, it is quite manageable and performs rather well.


NB: As for arrays or dictionaries to be stored with the entity to keep track of ordering information: this is possible via so-called "transformable" attributes, but the overhead is daunting. These attributes have to be serialized and deserialized, and in order to retrieve one sequence number you have to get all of them. Hardly an attractive design choice.

0
votes

Before we had ordered relationships for more than 10 years, everyone used a "helper" entity. So that is the thing that you should do.

Additional note 1: This is no "helper" entity. It is a entity that models a fact in your model. In my books I always had the same example:

You have a group entity with members. Every member can belong to many groups. The "helper" entity is nothing else than membership.

Additional note 2: It is hard to synchronize such an ordered relationship. This is why it is not done automatically. However, you have to do it. Since CD and synchronizing is no fun, CD and synchronizing a model with ordered relationship is less than no fun.