user580175
user580175

Reputation:

Error dealing with saveWithBlock and relation in MagicalRecord

I'm using MagicalRecord to change my custom CoreData functions with something better.

I have two entities: Offer (videogame offers) and System (consoles, PC, etx). An Offer can have one or many Systems, and I get all the data from a Parse query, where I save all my data.

I only have 8 Systems so when my app starts, I fetch all of them and save with Magical Record. Then I call my method to fetch some offers and transform the PFObjects from Parse into entities.

This is how

+ (void)createOrUpdateOffersWithArray:(NSArray *)objects completion:(void (^)())completion
{
 [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {

   for (PFObject *object in objects) {

     Offer *offer = [Offer MR_findFirstByAttribute:@"offerId" withValue:object.objectId inContext:localContext];

     if (offer == nil) {
       offer = [Offer MR_createEntityInContext:localContext];
     }

     // Here I set all the offer values (title, date, etc)... 


     NSSet *offerSavedSystems = [offer mutableSetValueForKey:@"systems"];

     if (offerSavedSystems == nil) {
       offerSavedSystems = [[NSMutableSet alloc] init];
     }

     /* This is a set of all the systems related with the offer */
     NSArray *offerSystems = [object objectForKey:@"sistemas"];

     NSMutableSet *updatedSystems = [[NSMutableSet alloc] init];

     /* Here I query one of my System entities for each in the "offerSystems" array */
     for (NSString *systemKey in offerSystems) {
       System *system = [System MR_findFirstByAttribute:@"key" withValue:systemKey inContext:localContext];
       [updatedSystems addObject:system];
     }

     offer.systems = updatedSystems;

  }

 } completion:^(BOOL contextDidSave, NSError *error) {

   /* UI update*/

  }];

}

The weird this happens inside the last for loop. Despite I'm sure that all the 8 systems are inside my CoreData model, this line

System *system = [System MR_findFirstByAttribute:@"key" withValue:systemKey inContext:localContext]; 

returns nil

But the most weird thing is that using NSLOG just before the for loop like this

  NSLog(@"SYSTEMS %d", [System MR_countOfEntities]);
  NSLog(@"SYSTEMS WITH LOCAL CONTEXT %d", [System MR_countOfEntitiesWithContext:localContext]);

I got this

  SYSTEMS 8
  SYSTEMS WITH LOCAL CONTEXT 0

My Systems are previously saved with this method

+ (void)initializeSystems
{
  NSArray *systemsKeys = [[self systems] allKeys];

  for (NSString *systemKey in systemsKeys) {

     System *system = [System MR_findFirstByAttribute:@"key" withValue:systemKey];

     if (system == nil) {
       system = [System MR_createEntity];
     }

     [MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) {
        system.key = systemKey;
        system.name = [self literalForSystem:systemKey];
        system.subscribed = [NSNumber numberWithBool:NO];
     }];
   }
 }

What I'm doing wrong?

Thanks for your time

Upvotes: 0

Views: 324

Answers (1)

Doro
Doro

Reputation: 2413

There are several possible problems with this line of code

System *system = [System MR_findFirstByAttribute:@"key" withValue:systemKey inContext:localContext];
  1. systemKey value does not exist inside all of your entities.
  2. system.key value not setted (or nil)

So, check firstly - fetch all system entities and log 'key' value. Insure that your key really exist.

Secondly,it's better to refactor your code for background saving

+ (void)initializeSystemsWithCompletion:(void (^)())completion
{

    [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {

        NSArray *systemsKeys = [[self systems] allKeys];

        for (NSString *systemKey in systemsKeys) {

            System *system = [System MR_findFirstByAttribute:@"key" withValue:systemKey inContext:localContext];

            if (system == nil) {
                system = [System MR_createEntityInContext:localContext];
            }

                system.key = systemKey;
                system.name = [self literalForSystem:systemKey];
                system.subscribed = [NSNumber numberWithBool:NO];
        }


    } completion:^(BOOL success, NSError *error) {

    }];

}

Upvotes: 0

Related Questions