Using Mantle with Core Data - NSSet and NSArray

3.2k views Asked by At

I need your help with something, as I can't get my head around this. I'm using Mantle together with CoreData in iOS.

I have relationships defined that look as follows:

Post 1:N Comment

When I pull the data from my REST Service, I create a Mantle Object Post that has a NSMutableArray of Comments in it. This works flawlessly.

I then store this in Core Data, and this is where I don't know whether I am doing things right.

[MTLManagedObjectAdapter managedObjectFromModel:post insertingIntoContext:[self getManagedObjectContext] error:&error];

So I'm doing this to store my post object into Core Data. The Core Data Model has a relationship called "post_has_comments" which is a cascading One-to-Many relationship. So on the object Post I have "posts_has_comments" -> cascading, on my object "Comment" I have a one-to-one relationship with "Nullify".

Afaik, Core Data treats this as a NSSet. What I'm trying to put in is a NSMutableArray though, as Mantle will take care of this (at least thats what a quick look in its source told me).

Unfortunately, when I get the object back from Core Data with

Post* post = [MTLManagedObjectAdapter modelOfClass:Post.class fromManagedObject:[[self fetchedResultsController] objectAtIndexPath:indexPath] error:nil];

The property comments on the post object is a empty NSSet, and I get quite some errors upon inserting the thing beforehand. The errors I get:

Core Data: annotation: repairing missing delete propagation for to-many relationship post_has_comments on object [...]

I am stuck - Maybe I am missing something huge here?

My Post Class implements the following static methods:

+ (NSDictionary *)managedObjectKeysByPropertyKey {
return @{
         @"post_id" : @"id",
         @"comments" : @"post_has_comments"
         };
}

+ (NSDictionary *)JSONKeyPathsByPropertyKey {
    return @{
             @"post_id" : @"id",
             };
}

+ (NSDictionary *)relationshipModelClassesByPropertyKey {
    return @{
             @"comments" : IHComment.class
             };
}
2

There are 2 answers

4
Mundi On BEST ANSWER

From the Mantle documentation:

Mantle makes it easy to write a simple model layer for your Cocoa or Cocoa Touch application.

This is simply an unproven statement. Looking at the framework, I do not see where the evidence is. You should get your objects, and insert them into Core Data using Apple's APIs.

Post *cdPost = [NSEntityDescription insertNewObjectForEntityForName:@"Post"
   inManagedObjectContext:self.managedObjectContext];
// configure the cdPost object with the data from the web service
for (id commentObject in commentArrayFromPostObject) {
   Comment *cdComment = 
       [NSEntityDescription insertNewObjectForEntityForName:@"Comment"
       inManagedObjectContext:self.managedObjectContext];
   // configure the cdComment object with the data from the web service
   cdComment.post = cdPost;
}

That's all there is to it.

0
Yas Tabasam On

A simple workaround is to write your own property setter method and if value being set is NSSet then convert it to NSMutableArray before setting it back to your property ivar.

For example:

- (void)setComments:(NSMutableArray *)comments {
    if ([comments isKindOfClass:NSSet.class]) {
        _comments = [NSMutableArray arrayWithArray:[((NSSet *)comments) allObjects]];
    } else {
        _comments = comments;
    }
}

I've done it myself quite a few times and it works like a charm!