Skip to main content

Running Database Fetch (Core Data) in Background Thread using magical Record


  To run database fetching in background thread(in a separate context), so that the UI does not get blocked:

__block NSMutableArray *dataArray= [[NSMutableArray alloc] init];
  // Create a child context of the main context
  NSManagedObjectContext *privateContext = [NSManagedObjectContext MR_context];
  // When using private contexts execute the core data code in it's private queue using performBlock: or performBlockAndWait:
  [privateContext performBlock:^{
    // Execute fetch
  NSArray *privateObjects;
  if(entity_predicate == nil) {
      //fetch all! duh!
      privateObjects = [self MR_findAllSortedBy:sort_key ascending:YES inContext:privateContext];
    } else {
      privateObjects = [self MR_findAllSortedBy:sort_key ascending:YES withPredicate:entity_predicate inContext:privateContext];
    }
   
    // Convert fetched objects into object IDs which can be pulled out of the main context
    NSArray *privateObjectIDs = [privateObjects valueForKey:@"objectID"];
    // Return to main thread
    dispatch_async(dispatch_get_main_queue(), ^{
      // Create a new predicate to pull objects out
      NSArray *finalResults;
      if(privateObjectIDs) {
      NSPredicate *mainPredicate = [NSPredicate predicateWithFormat:@"self IN %@", privateObjectIDs];
      // Execute fetch
        finalResults = [self MR_findAllWithPredicate:mainPredicate];
      }
      // use finalResults from the main thread
      [dataArray removeAllObjects];
      dataArray = [finalResults mutableCopy];
      if (fcb) {
        fcb(dataArray);
      }
     
    });
  }];

Comments