簡體   English   中英

iOS RestKit問題:無效的參數不令人滿意:responseDescriptors

[英]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 ,所以我有兩個建議:

  1. 如果可以更改JSON結構,請將頂級更改為{ events:[...] } ,並將keyPath:nil更改為keyPath:@"events"以反映此更改。

  2. 如果不可能, pathPattern:nil更改為pathPattern:@"/farmapp"注意,我將pathPattern:設置為與您的資源URL相匹配。 如果您還有其他類型的資源從該URL分支出來,則第二條建議可能不起作用。

另外,我注意到,您的errorDescriptor使用相同的映射( entityMapping )作為successDescriptor 我不知道這是否是您想要的,但是如果您的錯誤響應應該是其他錯誤對象,則建議您進行更改。

希望這可以幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM