RestKit addFetchRequestBlock causes objects not to be displayed

I have the following fetch request block configured to remove orphan objects:

  [objectManager addFetchRequestBlock:^NSFetchRequest *(NSURL *URL) {
    RKPathMatcher *pathMatcher = [RKPathMatcher pathMatcherWithPattern:API_GET_ACTIVE_RIDES];

    NSString * relativePath = [URL relativePath];
    NSDictionary *argsDict = nil;
    BOOL match = [pathMatcher matchesPath:relativePath tokenizeQueryStrings:NO parsedArguments:&argsDict];
    if (match) {
        NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Ride"];
        return fetchRequest;
    }

    return nil;
}];

      

Since I need to allow users to log out and log in, I remove all data from the master data using the following:

 + (void) clearUserData {
    NSError * error = nil;
    [[RKManagedObjectStore defaultStore] resetPersistentStores:&error];
    if(error != nil){
        [WRUtilities criticalError:error];
        return;
    }
}

      

However, if I log out and return to my application, the objects that were loaded the first time I logged in are not loaded from the server. Using the RestKit log I can see that the request disappears and returns the correct data from the server, but the display seems to be completely skipped, resulting in no objects being (re) inserted into the master data.

If I delete the fetch request block everything works as I would expect - clearUserData will delete all data and load the login, the data will be re-requested from the server and reloaded into the master data.

My question is twofold. What do I need to change to get the expected behavior of a successful data reload and why does a fetch query block, which I understand is only intended to delete orphaned objects, affect this scenario?

I've seen this before and was just deleting the fetch request block, but I'd rather use this feature rather than skip it because of this issue.

+3


source to share


1 answer


I had this exact problem and managed to find a solution. Basically, the code below will only return the fetch query if there are existing items in CoreData. The problem with returning all the time means that RestKit will delete the items you get from the server the first time. The idea here is to return nil if there are no elements in CoreData. Not sure if this would be recommended by RestKit, but it worked for me.

RKObjectManager *sharedManager = [RKObjectManager sharedManager];
[sharedManager addFetchRequestBlock:^NSFetchRequest *(NSURL *URL) {
    RKPathMatcher *userPathMatcher = [RKPathMatcher pathMatcherWithPattern:@"my/api/path"];
    BOOL match = [userPathMatcher matchesPath:[URL relativePath] tokenizeQueryStrings:NO parsedArguments:nil];
    if(match) {
        // lets first check if we have anything in coredata
        NSString * const entityName = NSStringFromClass([MyCoreDataEntity class]);
        NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:entityName];
        NSError *error = nil;
        NSManagedObjectContext *managedObjectContext = [RKManagedObjectStore defaultStore].mainQueueManagedObjectContext;
        NSArray *results = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
        if(error) {
            // this shouldn't happen, but if something went wrong querying CoreData
            // lets just save the new ones
            NSLog(@"error %@", error);
            return nil;
        }

        if([results count] > 0) {
            // if we already have something saved, lets delete 'em and save 
            // the new ones
            return [NSFetchRequest fetchRequestWithEntityName:entityName];
        }
        else {
            // if we don't have something saved, lets save them
            // (e.g. first time after login after we cleared everything on logout)
            return nil;
        }
    }
    return nil;
}];

      



Hope it helps!

+5


source







All Articles