Search code examples
ioscore-dataexecutefetchrequest

IOS/Objective-C: Load one record from Core Data without loading table first


For a profile screen, I would like to load the equivalent of a detail page from Core Data without having to load a table first. I have an entity/ table of multiple users in core data. But I'm only interested in pulling the profile data on one of them, the current user. I would like to load that directly without going through the process of loading a table and choosing a selection and using path and index row etc. Once I get the results, I don't want to display them as a row but rather distribute different fields around the page in different elements as you do in a detail page.

Can anyone suggest the best way to do this?

I imagine I need to use a predicate that sorts for the user in question with userid or username. Ordinarily I use NSFetchedResultsController to perform fetches but perhaps there is a way to do a simpler fetch with executefetchrequest. Following code is adapted from something I found on SO. Is it right approach?

 - (User *)userInfo:(NSDictionary *)usersList
            inManagedObjectContext:(NSManagedObjectContext *)context
{
    User *user = nil;

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Users"];
    request.predicate = [NSPredicate predicateWithFormat:@"username = bob"];
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"last" ascending:YES];
    request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];

    NSError *error = nil;

    NSArray *matches = [context executeFetchRequest:request error:&error];

    if (!matches || ([matches count] > 1)) {
        // handle error
    }  else {
        user = [matches lastObject];
    }

    return user;
}

Solution

  • What is wrong with your code? What doesn't it do?

    Based on your description, the code you provided does exactly what you are asking.

    As for your comment about loading a table, you never load a table. Core Data is an object model design. Even when you configure it to persist to SQLite you are still never "loading a table". You are loading a group of objects.

    Treating Core Data like it is an ORM is going to cause you more design problems later. It is an object graph not an ORM.

    The immediate error is I don't have the syntax right for calling the method. I am trying to call it in viewDidLoad with [self userInfo:?? inManagedObjectContext:(NSManagedObjectContext *)context but I don't know what to include as ??. However, before going crazy trying to get it to work, I wanted to find out if this was the right approach. Glad to hear that it is. Can you suggest how to call the method? I am fuzzy on what the dictionary is we are really calling here.

    The method is something you defined. What do you want that dictionary to contain? It is not part of the Core Data API it is a part of your view controller.

    The code in this method is fairly standard fair. A simple fetch against Core Data.

    If you did not write this method, then I would suggest you ask the person who did write it.

    FYI, Nothing in that dictionary is being used in the predicate. Would this happen to be a homework assignment?