FetchRequest 不 return 通过 RestKit 0.2 获取的 NSManagedObjects
FetchRequest does not return NSManagedObjects fetched via RestKit 0.2
我遇到以下问题:我使用 RestKit 从 REST 中获取对象 Api。对象映射有效,我可以从 RK 调试器输出中看到这一点。但是,当我之后执行提取请求时,结果是空的。我说的是 NSManagedObjects。我有以下设置。
1:Restkit和Coredata栈初始化:
NSError *error;
NSURL *baseURL = [NSURL URLWithString:@"https://mfihost.us/gocoffee/api/V1/"];
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:baseURL];
[objectManager.HTTPClient setDefaultHeader:@"Token" value:[NSString stringWithFormat:@"%@",[FBSDKAccessToken currentAccessToken].tokenString]];
objectManager.requestSerializationMIMEType = RKMIMETypeJSON;
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
objectManager.managedObjectStore = managedObjectStore;
//[RKObjectManager setSharedManager:objectManager];
[FetchRequests registerFetchRequests:objectManager];
[Descriptors registerDescriptors:objectManager];
[managedObjectStore createPersistentStoreCoordinator];
NSPersistentStore *persistentStore = [managedObjectStore addInMemoryPersistentStore:&error];
NSAssert(persistentStore, @"Failed to add inmemory store with error: %@", error);
[managedObjectStore createManagedObjectContexts];
managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];
2:调用从服务器获取对象并随后执行获取请求:
[[RKObjectManager sharedManager]
postObject:nil path:@"/gocoffee/api/V1/login/IOS"
parameters:nil
success: ^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(@"Objects have been saved in core data.");
NSManagedObjectContext *managedObjCtx = [RKManagedObjectStore defaultStore].mainQueueManagedObjectContext;
// Shout* sh=[managedObjCtx insertNewObjectForEntityForName:@"Shout"];
// sh.inviterUserId=@"22223";
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Shout" inManagedObjectContext:managedObjCtx];
[fetchRequest setEntity:entity];
NSError *error = nil;
NSArray *result = [managedObjCtx executeFetchRequest:fetchRequest error:&error];
if (error) {
NSLog(@"Unable to execute fetch request.");
NSLog(@"%@, %@", error, error.localizedDescription);
} else {
NSLog(@"%@", result);
}
completionBlock();
}
failure: ^(RKObjectRequestOperation *operation, NSError *error) {
RKLogError(@"Load failed with error: %@", error);
}];
尽管服务器 returns 对象和这些对象已通过使用 RKEntityMappings 和相应的响应描述符正确映射,但获取结果为空。令人困惑的是,如果我取消注释这两行 //Shout * ....(即手动将托管对象插入上下文),那么该对象将由获取请求获取。因此,获取请求应该可以正常工作。
我现在正在寻找年龄问题可能是什么。可能是我调用了错误的上下文或其他什么?顺便说一句:核心数据多线程调试已启用并且没有显示任何错误,即没有"AllThatIsLeftToUsIsHonor"错误。
上例对应的路由为:
[objectManager.router.routeSet
addRoute:[RKRoute routeWithName:@"loginAndOrSignup"
pathPattern:@"login/IOS"
method:RKRequestMethodPOST]
];
描述符看起来像(示例):
[objectManager addResponseDescriptor:
[RKResponseDescriptor responseDescriptorWithMapping:[shoutMapping inverseMapping]
method:RKRequestMethodPOST
pathPattern: @"login/IOS"
keyPath:@"response.incomingshoutapplications"
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)
]
];
喊映射如下:
RKEntityMapping *shoutMapping = [RKEntityMapping mappingForEntityForName:@"Shout" inManagedObjectStore:managedObjectStore];
shoutMapping.identificationAttributes = @[ @"id" ];
[shoutMapping addAttributeMappingsFromDictionary:@{
@"id" : @"id",
@"inviterUserId" : @"inviterUserId",
@"eventType" : @"eventType",
@"eventTime" : @"eventTime",
@"locationLat" : @"locationLat",
@"locationLng" : @"locationLng",
@"radius" : @"radius",
@"targetGender" : @"targetGender",
@"state" : @"state",
@"buddyOnly" : @"buddyOnly",
@"timeCreated" : @"timeCreated"
}
];
"manager" 是上面那个,managedObjectStore 是 manager.managedObjectStore
所有映射和描述符都在另一个方法中设置,该方法由 [Descriptors registerDescriptors:objectManager] 调用; (见第一段代码)
问题可能是您正在使用 inverseMapping
。这主要用于请求映射,因为它是创建 NSMutableDictionary
实例的映射,这不是您想要的。
所以,我期望发生的是响应被成功映射,但是映射到普通对象,而不是托管对象,然后你就把结果扔掉了。
改成
... responseDescriptorWithMapping:shoutMapping ...
我遇到以下问题:我使用 RestKit 从 REST 中获取对象 Api。对象映射有效,我可以从 RK 调试器输出中看到这一点。但是,当我之后执行提取请求时,结果是空的。我说的是 NSManagedObjects。我有以下设置。
1:Restkit和Coredata栈初始化:
NSError *error;
NSURL *baseURL = [NSURL URLWithString:@"https://mfihost.us/gocoffee/api/V1/"];
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:baseURL];
[objectManager.HTTPClient setDefaultHeader:@"Token" value:[NSString stringWithFormat:@"%@",[FBSDKAccessToken currentAccessToken].tokenString]];
objectManager.requestSerializationMIMEType = RKMIMETypeJSON;
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
objectManager.managedObjectStore = managedObjectStore;
//[RKObjectManager setSharedManager:objectManager];
[FetchRequests registerFetchRequests:objectManager];
[Descriptors registerDescriptors:objectManager];
[managedObjectStore createPersistentStoreCoordinator];
NSPersistentStore *persistentStore = [managedObjectStore addInMemoryPersistentStore:&error];
NSAssert(persistentStore, @"Failed to add inmemory store with error: %@", error);
[managedObjectStore createManagedObjectContexts];
managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];
2:调用从服务器获取对象并随后执行获取请求:
[[RKObjectManager sharedManager]
postObject:nil path:@"/gocoffee/api/V1/login/IOS"
parameters:nil
success: ^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(@"Objects have been saved in core data.");
NSManagedObjectContext *managedObjCtx = [RKManagedObjectStore defaultStore].mainQueueManagedObjectContext;
// Shout* sh=[managedObjCtx insertNewObjectForEntityForName:@"Shout"];
// sh.inviterUserId=@"22223";
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Shout" inManagedObjectContext:managedObjCtx];
[fetchRequest setEntity:entity];
NSError *error = nil;
NSArray *result = [managedObjCtx executeFetchRequest:fetchRequest error:&error];
if (error) {
NSLog(@"Unable to execute fetch request.");
NSLog(@"%@, %@", error, error.localizedDescription);
} else {
NSLog(@"%@", result);
}
completionBlock();
}
failure: ^(RKObjectRequestOperation *operation, NSError *error) {
RKLogError(@"Load failed with error: %@", error);
}];
尽管服务器 returns 对象和这些对象已通过使用 RKEntityMappings 和相应的响应描述符正确映射,但获取结果为空。令人困惑的是,如果我取消注释这两行 //Shout * ....(即手动将托管对象插入上下文),那么该对象将由获取请求获取。因此,获取请求应该可以正常工作。 我现在正在寻找年龄问题可能是什么。可能是我调用了错误的上下文或其他什么?顺便说一句:核心数据多线程调试已启用并且没有显示任何错误,即没有"AllThatIsLeftToUsIsHonor"错误。
上例对应的路由为:
[objectManager.router.routeSet
addRoute:[RKRoute routeWithName:@"loginAndOrSignup"
pathPattern:@"login/IOS"
method:RKRequestMethodPOST]
];
描述符看起来像(示例):
[objectManager addResponseDescriptor:
[RKResponseDescriptor responseDescriptorWithMapping:[shoutMapping inverseMapping]
method:RKRequestMethodPOST
pathPattern: @"login/IOS"
keyPath:@"response.incomingshoutapplications"
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)
]
];
喊映射如下:
RKEntityMapping *shoutMapping = [RKEntityMapping mappingForEntityForName:@"Shout" inManagedObjectStore:managedObjectStore];
shoutMapping.identificationAttributes = @[ @"id" ];
[shoutMapping addAttributeMappingsFromDictionary:@{
@"id" : @"id",
@"inviterUserId" : @"inviterUserId",
@"eventType" : @"eventType",
@"eventTime" : @"eventTime",
@"locationLat" : @"locationLat",
@"locationLng" : @"locationLng",
@"radius" : @"radius",
@"targetGender" : @"targetGender",
@"state" : @"state",
@"buddyOnly" : @"buddyOnly",
@"timeCreated" : @"timeCreated"
}
];
"manager" 是上面那个,managedObjectStore 是 manager.managedObjectStore 所有映射和描述符都在另一个方法中设置,该方法由 [Descriptors registerDescriptors:objectManager] 调用; (见第一段代码)
问题可能是您正在使用 inverseMapping
。这主要用于请求映射,因为它是创建 NSMutableDictionary
实例的映射,这不是您想要的。
所以,我期望发生的是响应被成功映射,但是映射到普通对象,而不是托管对象,然后你就把结果扔掉了。
改成
... responseDescriptorWithMapping:shoutMapping ...