![](/img/trans.png)
[英]RestKit Mapping Invalid parameter not satisfying: managedObjectStore
[英]iOS RestKit issue: Invalid parameter not satisfying: responseDescriptors
我正在嘗試使用RestKit來檢索事件列表,而我一直這樣:
2013-05-20 10:52:56.708 EventApp[3380:c07] I restkit:RKLog.m:34 RestKit logging initialized...
2013-05-20 10:52:56.773 EventApp[3380:c07] *** Assertion failure in -[RKObjectRequestOperation initWithRequest:responseDescriptors:], /Users/mitchell/Desktop/eventapp/take2/EventApp/Pods/RestKit/Code/Network/RKObjectRequestOperation.m:158
2013-05-20 10:52:56.774 EventApp[3380:c07] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: responseDescriptors'
幾天來,我一直在撓頭。 由於我的iOS開發技能有很多空白(每年大約一個項目),如果有人可以使用一些外行術語將我引向正確的方向,這將大有幫助。
請考慮我正在使用enqueueObjectRequestOperation專門用於批處理多個請求。 我剛剛將我的代碼片段拼湊在一起,在這里進行翻譯。
這是我的數據模型:
JSON文件如下所示:
[{
"id":1,
"farm_id":1,
"all_day": "NO",
"from": "2013-05-08T18:45:38Z",
"to": "2013-05-08T18:45:38Z",
"name": "event 1",
"desc": "some description",
"photo": "some.png",
"price": "price"
}]
這是我的代碼:
NSManagedObjectContext *context;
RKObjectManager *objectManager;
if (self.eventContext == nil) {
NSError *error = nil;
NSURL *modelURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"FarmApp" ofType:@"momd"]];
RKEntityMapping *entityMapping;
// NOTE: Due to an iOS 5 bug, the managed object model returned is immutable.
NSManagedObjectModel *managedObjectModel = [[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL] mutableCopy];
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
// Initialize the Core Data stack
[managedObjectStore createPersistentStoreCoordinator];
NSPersistentStore __unused *eventPersistentStore = [managedObjectStore addInMemoryPersistentStore:&error];
NSAssert(eventPersistentStore, @"Failed to add persistent store: %@", error);
[managedObjectStore createManagedObjectContexts];
// Set the default store shared instance
[RKManagedObjectStore setDefaultStore:managedObjectStore];
// Configure the object manager
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://sandbox.bm.com"]];
[RKObjectManager setSharedManager:objectManager];
[objectManager setRequestSerializationMIMEType:@"application/json"];
[objectManager setAcceptHeaderWithMIMEType:@"text/plain"];
objectManager.managedObjectStore = managedObjectStore;
entityMapping = [RKEntityMapping mappingForEntityForName:@"Event" inManagedObjectStore:managedObjectStore];
[entityMapping addAttributeMappingsFromDictionary:@{
@"id": @"eventID",
@"farm_id": @"farm",
@"all_day": @"allDay",
@"from": @"from",
@"to": @"to",
@"name": @"name",
@"desc": @"desc",
@"photo": @"photo",
@"price": @"price"
}];
RKResponseDescriptor *successDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:entityMapping pathPattern:nil keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:successDescriptor];
RKResponseDescriptor *errorDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:entityMapping pathPattern:nil keyPath:@"errors" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassClientError)];
[objectManager addResponseDescriptor:errorDescriptor];
self.eventContext = managedObjectStore.mainQueueManagedObjectContext;
}
context = self.eventContext;
NSString* url = [NSString stringWithFormat:@"http://sandbox.bm.com/farmapp/%@.json", @"events"];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:[objectManager responseDescriptors]];
[operation setCompletionBlockWithSuccess:nil failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"Loaded this error: %@", [error localizedDescription]);
}];
NSArray *operations = [NSArray arrayWithObjects:operation, nil];
for (int i = 0; i < [operations count]; i++ ) {
[[RKObjectManager sharedManager] enqueueObjectRequestOperation:[operations objectAtIndex:i]];
}
有人可以幫我嗎?
這是最終的解決方案
if (self.eventContext == nil) {
NSManagedObjectContext *context;
RKObjectManager *objectManager;
NSError *error = nil;
NSURL *modelURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"FarmApp" ofType:@"momd"]];
RKEntityMapping *entityMapping;
// NOTE: Due to an iOS 5 bug, the managed object model returned is immutable.
NSManagedObjectModel *managedObjectModel = [[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL] mutableCopy];
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
// Initialize the Core Data stack
[managedObjectStore createPersistentStoreCoordinator];
NSPersistentStore __unused *eventPersistentStore = [managedObjectStore addInMemoryPersistentStore:&error];
NSAssert(eventPersistentStore, @"Failed to add persistent store: %@", error);
[managedObjectStore createManagedObjectContexts];
// Set the default store shared instance
[RKManagedObjectStore setDefaultStore:managedObjectStore];
// Configure the object manager
objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://sandbox.bm.com"]];
[RKObjectManager setSharedManager:objectManager];
[objectManager setRequestSerializationMIMEType:@"application/json"];
[objectManager setAcceptHeaderWithMIMEType:@"text/plain"];
objectManager.managedObjectStore = managedObjectStore;
entityMapping = [RKEntityMapping mappingForEntityForName:@"Event" inManagedObjectStore:managedObjectStore];
[entityMapping addAttributeMappingsFromDictionary:@{
@"id": @"eventID",
//@"farm_id": @"farm",-->cannot create relationship this way
@"farm_id" : @"farmID",//farmID attribute needs to be added to Event's model
@"all_day": @"allDay",
@"from": @"from",
@"to": @"to",
@"name": @"name",
@"desc": @"desc",
@"photo": @"photo",
@"price": @"price"
}];
[entityMapping addConnectionForRelationship:@"farm" connectedBy:@"farmID"];
RKResponseDescriptor *successDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:entityMapping pathPattern:nil keyPath:@"events" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:successDescriptor];
RKResponseDescriptor *errorDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:entityMapping pathPattern:nil keyPath:@"errors" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassClientError)];
[objectManager addResponseDescriptor:errorDescriptor];
self.eventContext = managedObjectStore.mainQueueManagedObjectContext;
context = self.eventContext;
NSString* url = [NSString stringWithFormat:@"http://sandbox.bm.com/farmapp/%@.json", @"events"];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
RKManagedObjectRequestOperation *operation = [objectManager managedObjectRequestOperationWithRequest:request managedObjectContext:managedObjectStore.mainQueueManagedObjectContext success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(@"Success");
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"Failure");
}];
NSArray *operations = [NSArray arrayWithObjects:operation, nil];
for (int i = 0; i < [operations count]; i++ ) {
[[RKObjectManager sharedManager] enqueueObjectRequestOperation:[operations objectAtIndex:i]];
}
}
作為@JoelH。 建議在他的評論之一中,您需要使用RKManagedObjectRequestOperation而不是RKObjectRequestOperation。
例如 :
RKManagedObjectRequestOperation *operation = [objectmanager managedObjectRequestOperationWithRequest:request managedObjectContext:managedObjectStore.mainQueueManagedObjectContext success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(@"Success");
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"Failure");
}];
此外,我認為您的映射方式
@"farm_id": @"farm"
是不正確的。
如果要建立事件和服務器場之間的關系,則需要使用以下方法之一: RelationshipMappingFromKeyPath:toKeyPath:withMapping:或addConnectionForRelationship:connectedBy:
如果Farm對象已經存在,並且您只想映射新的Event,我將使用addConnectionForRelationship:connectedBy:
例如 :
RKEntityMapping* eventMapping = [RKEntityMapping mappingForEntityForName:@"Event" inManagedObjectStore:managedObjectStore];
[entityMapping addAttributeMappingsFromDictionary:@{
@"id": @"eventID",
//@"farm_id": @"farm",-->cannot create relationship this way
@"farm_id" : @"farmID",//farmID attribute needs to be added to Event's model
@"all_day": @"allDay",
@"from": @"from",
@"to": @"to",
@"name": @"name",
@"desc": @"desc",
@"photo": @"photo",
@"price": @"price"
}];
[eventMapping addConnectionForRelationship:@"farm" connectedBy:@"farmID"];
由於RestKit 不允許沒有中間屬性的關系連接 ,因此還需要在Event模型中添加farmID屬性。
RestKit文檔( Mapping Without KVC )似乎暗示着,如果您在頂層沒有KVC標簽(例如events:[]
),則解析器需要pathPattern:
才能知道要使用哪個映射。 由於您的keyPath:
和pathPattern:
對於您的successDescriptor
都是nil
,所以我有兩個建議:
如果可以更改JSON結構,請將頂級更改為{ events:[...] }
,並將keyPath:nil
更改為keyPath:@"events"
以反映此更改。
如果不可能, pathPattern:nil
更改為pathPattern:@"/farmapp"
注意,我將pathPattern:
設置為與您的資源URL相匹配。 如果您還有其他類型的資源從該URL分支出來,則第二條建議可能不起作用。
另外,我注意到,您的errorDescriptor
使用相同的映射( entityMapping
)作為successDescriptor
。 我不知道這是否是您想要的,但是如果您的錯誤響應應該是其他錯誤對象,則建議您進行更改。
希望這可以幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.