RestKit addFetchRequestBlock导致不映射对象

时间:2014-08-18 01:56:07

标签: ios restkit

我设置了以下获取请求块来处理孤立对象的删除:

  [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;
}];

由于我需要允许用户注销并重新登录,因此我使用以下内容清除核心数据中的所有数据:

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

但是,如果我退出并重新登录到我的应用程序,则第一次登录时加载的对象不会从服务器加载。使用RestKit日志记录,我可以看到请求已经发出并从服务器返回正确的数据,但是映射似乎被完全跳过,导致没有对象(重新)插入到核心数据中。

如果我删除了我的获取请求块,一切都按预期工作 - clearUserData删除所有数据,上传登录数据从服务器重新查询并重新加载到核心数据。

我的问题有两个问题。我需要更改什么才能获得成功重新加载数据的预期行为,为什么获取请求块(我理解为仅用于删除孤立对象)会对此方案产生影响?

之前我已经看过这个并且刚刚删除了获取请求块,但我更喜欢使用此功能而不是因为这个问题而跳过它。

1 个答案:

答案 0 :(得分:5)

我遇到了这个问题,并设法找到了解决方案。基本上,如果CoreData中存在现有项,则下面的代码将仅返回获取请求。一直返回它的问题意味着RestKit将首次删除您从服务器获得的项目。这里的想法是,如果CoreData中当前没有任何项目,则返回nil。不确定这是否是RestKit推荐的方式,但它对我有用。

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;
}];

希望有所帮助!