Search code examples
ioscore-datansmanagedobjectcontextnsfetchrequest

One FetchRequest on two ManagedObjectContexts


I have two Managed Object Contexts with the same data model. The only difference is that one is readonly and the other is read/write. I want to search for an object that can be in either of those two managed object contexts. So I create a fetchrequest and want to use the fetchrequest on both managed object contexts.

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Person"];
[fetchRequest setIncludesPendingChanges:YES];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"name=%@", name];

NSError *error = nil;
NSArray *privateobjects = [self.privateManagedObjectContext executeFetchRequest:fetchRequest error:&error];
if (privateobjects && privateobjects.count > 0)
{
    return privateobjects[0];
}

NSArray *publicobjects = [self.publicManagedObjectContext executeFetchRequest:fetchRequest error:&error];
if (publicobjects && publicobjects.count > 0)
{
    return publicobjects[0];
}

return nil;

The above code doesn't return results from the public managed object context. I can fix this by recreating the fetchrequest. So my question, why does one fetchrequest not work on both managed object contexts?

Edit: After some more research it seems that the fetchrequest works on both managed object contexts when both contexts are saved. Whenever you search for pending changes the public (second) context doesn't return results.


Solution

  • I believe that you have to create the fetch request twice because it is dependent on the managed object context. The NSFetchRequest(entityName:) is really a shorthand for a fetch request with a certain NSEntityDescription, but without the managed object context. The context filled in in the last moment when you execute the fetch request with the NSManagedObjectContext method. (The NSEntityDescription factory method includes the context).

    So you might try to create a convenience method that returns such an "incomplete" fetch request and then use it with different contexts. (Not sure if this works, but if it does it will save you about 2-3 lines of code). Alternatively, just write the code for creating the fetch request again.