Jakub
Jakub

Reputation: 13860

NSOrderedSet response from server and Core Data

I want to show data as it came from the backend So let's have an example json file:

{
  "fonts": [
    {
      "name": "Helvetica",
      "styleIdentifier": "H0",
      "size": 17
    },
    {
      "name": "Helvetica",
      "styleIdentifier": "H1",
      "size": 14
    },
    {
      "name": "Helvetica-Bold",
      "styleIdentifier": "H0Bold",
      "size": 17
    },
    {
      "name": "HelveticaNeue-Light",
      "styleIdentifier": "H0Light",
      "size": 40
    }
  ]
}

So i create a relationship (many - many) with ordered option selected. And by the input i see it's always write in the same way to Core Data, but when I try to fetch it

configuratation.fonts where fonts is a NSOrderedSet i get items in completly random order. I miss sth in spec? Or I should sort it somehow?

__EDIT__

Firstly when i get a data from above json I have a configuration set with empty font relation. Then I fetch this and insert it into core data with:

NSMutableArray *returnArray = [NSMutableArray new];
for(NSDictionary *fontDictionary in jsonArray) {
    Font *fontObj = [Font font:fontDictionary inContext:context];
    [returnArray addObject:fontObj];
}

And in this array data is in correct order. Then in configuration object i add it to NSOrderedSet by:

-(void)appendTracks:(NSArray<Font*>*)fontArray {
    self.fonts = [NSOrderedSet orderedSetWithArray: fontArray];
}

And then i try to fetch it by simply use reference:

configuration.fonts

And in this step data are completly not in correct order.

Upvotes: 6

Views: 383

Answers (2)

shallowThought
shallowThought

Reputation: 19602

Do not set the NSOrderedSet directly.

Either modify the existing set:

[self.fonts addObjectsFromArray:fontArray];

Or:

Xcode generates methods to add and remove entries from ordered sets within the generated NSManagedObject class.

Assuming you have an Entity called ManagedConfiguration which holds an ordered to many relation called fonts:

ManagedConfiguration *managedObjectConfigurationInstance = //create or fetch configuration in ManagedObjectContext
NSOrderedSet<ManagedFont> *fonts = //created or fetched fonts in wanted order
managedObjectConfigurationInstance.addToFonts(fonts)

replaceFonts, removeFromFontsAtIndex aso. methods are also generated.


Depending on your requirements, you might want to store the fonts in random order and apply a NSSortDescriptor to your NSFetchRequest to fetch the data in a specific order.

Upvotes: 2

Arun Balakrishnan
Arun Balakrishnan

Reputation: 1502

Instead of trying to set the data directly to your property(fonts), you need to first fetch the mutable copy of your NSOrderedSet from the NSmanagedObject Subclass (I assume it to be Font).

NSMutableOrderedSet *orderedSet = [self mutableOrderedSetValueForKey:@"fonts"];

Then add the objects from the array to this orderedSet.

[orderedSet addObjectsFromArray:array];

Now you would have properly set the the values for the key fonts. So your appendTracks function would now look like this.

-(void)appendTracks:(NSArray<Font*>*)fontArray {
    NSMutableOrderedSet *orderedSet = [self mutableOrderedSetValueForKey:@"fonts"];
    [orderedSet addObjectsFromArray:fontArray];
}

Now execute your fetch request. You should receive the data in the set order in the array.

PS:I had used your JSON response to test this.

Upvotes: 1

Related Questions