7

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
             };
}
Elysium
  • 155
  • 1
  • 10

2 Answers2

0

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!

Yas Tabasam
  • 10,517
  • 9
  • 48
  • 53
-5

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.

Mundi
  • 79,884
  • 17
  • 117
  • 140
  • Well, the answer is not completely correct, but pointed me in the right direction. I found out that while Mantle does support CoreData, it has its problems and caveats with reversing relationships in CoreData. A solution is to simply manage this yourself, or avoid using Mantle until further improvements are made. Also, I had a really nasty bug serverside and Mantle in combination with CoreData tripped over it really badly without giving any exceptions. :( – Elysium Jan 23 '14 at 14:29
  • I read through my code again - just out of interest: what exactly is not completely correct? – Mundi Jan 23 '14 at 23:14
  • The code is perfectly fine. "You should get your objects, and insert them into Core Data using Apple's APIs." Mantle provides its own interfaces to do that: `[MTLManagedObjectAdapter managedObjectFromModel:car insertingIntoContext:self.masterManagedObjectContext error:NULL];` This makes it possible to also get Mantle Objects out of Core Data, which is useful as these objects can then get easily serialized to JSON via Mantle. – Elysium Jan 24 '14 at 14:14
  • OK, I see. But you did not take into account my previous arguments. In the light of these statements, you would first have to give evidence about the "easy" part quoted above before labelling my suggestion as "not completely correct". – Mundi Jan 24 '14 at 14:25