Question

I'm using GCD as well as Core Data. I'm aware Core Data is not thread safe, so I create child Managed Object Context (tempContext) with the mainContext as the parent. MainContext has a PCS to save data. What I'm doing is:

  1. Pull posts from Facebook
  2. Save each post to Core Data by creating a new Managed Object called Post, updating it and saving it
  3. while I process each post, if it needs additional handling, I add the post.obectID to an NSMutableArray of Managed Object IDS. This NSMutableArray is used by another process to finish updating the posts. I am using object IDs because the separate process will not be in the same tempContext, thus I will fetch the Post from Core Data using the object ID.

The process gets data, and I see it is stored within store.data (I use the product called Base to view the physical database file's content). But, I cannot seem to store the post's Object ID. As you see in code, I am using NSLog to print out the post's object ID, and I see them, thus I know the object IDs are there. Code also shows I am doing [tempContext save] and I am doing [mainContext save:], thus I should now have permanent, not temporary object IDs for posts. Again, the data is within Core data's physical file, but the mutable array count is still = 0.

What am I doing wrong to save the object IDs to NSMutableArray? In code you will see commented out where I've tried running the [mutableArray addObject:p.objectID] even on the main Queue, but it does not matter.

Here is my code:

- (void)processPosts {

NSLog(@"-- Begin processPosts --");

dispatch_async(_processPostsQ, ^{

    for (NSDictionary * info in _posts)
    {
        NSManagedObjectContext * tempContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
        tempContext.parentContext = mainMOContext;

        // If Post exists, rewrite over top of it. otherwise create a new one
        NSFetchRequest      * fetchRequest = [[NSFetchRequest alloc] init];
        NSEntityDescription * entity       = [[mainMOModel entitiesByName] objectForKey:@"Post"];

        [fetchRequest setEntity:entity];

        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"fb_post_id = %@",
                                  [info objectForKey:@"post_id"]];

        [fetchRequest setPredicate:predicate];

        NSSortDescriptor *sd = [NSSortDescriptor sortDescriptorWithKey:@"fb_post_id" ascending:YES];
        [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sd]];

        NSError * error = nil;
        NSArray * fetchResults = [tempContext executeFetchRequest:fetchRequest error:&error];

        Post * p = [NSEntityDescription insertNewObjectForEntityForName:@"Post" inManagedObjectContext:tempContext];

        if (fetchResults.count > 0)
        {
            p = [fetchResults objectAtIndex:0];
        }

        NSDictionary * appData = [[NSDictionary alloc]init];
        appData = [info objectForKey:@"app_data"];

        p.fb_actor_id       = [info objectForKey:@"actor_id"];
        p.fb_app_data       = [self archivedData:[info objectForKey:@"app_data"]];
        p.fb_attachment     = [self archivedData:[info objectForKey:@"attachment"]];
        p.fb_created_time   = [info objectForKey:@"created_time"];
        p.timestamp         = [info objectForKey:@"updated_time"];
        p.fb_attribution    = NULL_TO_NIL([info objectForKey:@"attribution"]);
        p.fb_message        = NULL_TO_NIL([info objectForKey:@"message"]);
        p.fb_type           = NULL_TO_NIL([info objectForKey:@"type"]);
        p.fb_post_id        = [info objectForKey:@"post_id"];
        p.fb_likes_info     = [self archivedData:[info objectForKey:@"like_info"]];
        p.fb_comments_info  = [self archivedData:[info objectForKey:@"comment_info"]];
        p.fb_parent_post_id = NULL_TO_NIL([info objectForKey:@"parent_post_id"]);
        p.fb_permalink      = NULL_TO_NIL([info objectForKey:@"permalink"]);
        p.fb_photo_data     = nil;
        p.fb_place          = NULL_TO_NIL([info objectForKey:@"places"]);
        p.fb_source_id      = [info objectForKey:@"source_id"];
        p.social_network    = @"facebook";
        p.fkPostToFriend    = [[FriendStore sharedStore]findFriendWithFBUID:[info objectForKey:@"source_id"] withMOContext:tempContext];

        [tempContext save:&error];

        dispatch_async(dispatch_get_main_queue(), ^{
            NSError * error;
            [mainMOContext save:&error];
        });


        if (appData.count > 0)
        {
            if ([[appData objectForKey:@"photo_ids"] count] > 0)
            {
                NSLog(@"   -- photos need to be loaded for postID: %@",p.objectID);
                //dispatch_async(dispatch_get_main_queue(), ^{
                    [_postsNeedingPhotos addObject:p.objectID];
                //});
            }
        }
    }

    NSLog(@"ProcessPosts: num of posts needing photos: %d",_postsNeedingPhotos.count);
    dispatch_async(_getPhotosQ, ^{
        [self loadPhotoData];
    });
    NSLog(@"-- End processPosts --");
});

}

Thanks in advance for your help!

Was it helpful?

Solution

I'm an idiot. I forgot to initialize _postsNeedingPhotos with:

_postsNeedingPhotos = [[NSMutableArray alloc] init];

Now everything runs fine... :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top