14

I'm currently designing a CloudKit based syncing-solution and I wondered what the best way is to keep the order of a list (an array in my case) of cloud items (CKRecord objects) consistent.

Apple advises against holding a reference to child objects and instead just reference the parent object with a CKReference from the child. This works fine if you want to query your items based on one of it's properties (e.g. a creation date), but not if you have have an order which is determined by the user.

I've come up with two different approaches which are based on the same idea: maintain a manifest of identifiers to manage the item's position.

1) Sync an extra record (aka manifest) which has an array of identifiers, each identifying a CKRecord object (and the corresponding local model object).

2) Create a parent object which holds an array of references (CKReference objects) to it's child objects. This array maintains the given order.

I feel that this is not quite the best possible solution to this problem and I would be glad to hear what you think.

Dharmesh Dhorajiya
  • 3,976
  • 9
  • 30
  • 39
JanApotheker
  • 1,746
  • 1
  • 17
  • 23
  • Add an `index` field to the child? – Paulw11 Feb 27 '15 at 05:04
  • This would require to **always** update all childs when performing a list operation (like adding or deleting an item). – JanApotheker Feb 27 '15 at 05:27
  • @JanApotheker, not really. `NSArray` keeps it's order even if you insert a new object in between other objects using `indexes`. – l'L'l Feb 27 '15 at 10:02
  • @l'L'l What I mean is that all following indexes behind the inserted/deleted item needs to be shifted by one. – JanApotheker Feb 27 '15 at 10:37
  • It does that automatically using `NSMutableIndexSet indexSetWithIndex` and `indexes addIndex`. If you want an example let me know - i got a few minutes to kill. – l'L'l Feb 27 '15 at 10:39
  • Right, but there is no `NSArray` oder `NSIndexSet` in my cloud container. The items are stored as single `CKRecord` objects which don't know (and probably should not know) anything about their position in my local list. – JanApotheker Feb 27 '15 at 10:46
  • Why not read the array from `CKRecord` into an `NSMutableArray` and deal with it there? That's what would need to happen. The array in `CKRecord` should stay ordered there until you need to change it. – l'L'l Feb 27 '15 at 10:55

1 Answers1

10

Apple does advises against holding a reference to child objects but that does not mean you can't just include an array with record Id's in your object. These does not have to be CKReference objects. You could just save an array of string values.

I think you are right that this would be the best/easiest approach for maintaining a sort order.

One other solution would be to create a linked list. Each record then needs a reference to the next record. When changing the order, then you only need to change 3 records. 1 the record that did point to your record, the new record that will point to your record and the record itself.

Edwin Vermeer
  • 13,017
  • 2
  • 34
  • 58
  • Thanks for you answer. Am I right that you suggesting to store an array of (string-) identifiers in the parent object? – JanApotheker Feb 27 '15 at 10:49
  • 1
    That would be the easiest thing to maintain. Then your child objects still would have a reference to it's parent object. The array of ID's in the parent object is then only used for the manual sort order. – Edwin Vermeer Feb 27 '15 at 11:08