Search code examples
objective-ccore-datansmanagedobjectnsfetchrequest

Is there a faster way to check if thousands of NSManagedObject items exist?


I'll use the example of a Google Reader client here, since that's what I'm actually doing...

I'm pulling in (potentially thousands of) items from a Google Reader account, and I'm wondering if there's a faster way to go about checking if I've already got an item (NSManagedObject) in the data store. Google Reader gives each item a unique string ID, which I'm storing in my NSManagedObjects. Here are the stripped down basics of what I do when importing. Note that I do use background threads, but I've stripped them out here for the sake of clarity.

Could I be doing this more efficiently?

- (void)importBatchOfItems:(NSArray *)itemsFromGoogleReader isLastBatch:(BOOL)isLastBatch {
  for (NSDictionary *item in *itemsFromGoogleReader) {
    NSManagedObject *feedItem = [self feedItemWithId:[item valueForKey:@"GoogleReaderItemID"]];
    if (feedItem == nil) {
      feedItem = [self insertFeedItem];
    }

    // ... do some stuff with feedItem
  }

  BOOL saveIntervalElapsed = (([NSDate timeIntervalSinceReferenceDate] - self.lastBatchSave) >= kBatchSaveInterval);

  if (saveIntervalElapsed || isLastBatch) {
    [self saveContext];
  }
}

- (NSManagedObject *)feedItemWithId:(NSString *)itemId {
  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id = %@", itemId];

  [self.uniqueItemFetchRequest setPredicate:predicate];
  NSArray *items = [self.managedObjectContext executeFetchRequest:self.uniqueItemFetchRequest error:nil];

  if ([items count] > 0) {
    return [items objectAtIndex:0];
  } else {
    return nil;
  }
}

Solution

  • Look at the Apple docs for Efficiently Importing Data they have several different ways of importing data for different scenarios with code snippets.