我遇到了两种JSON格式:
格式A:
[
{"topic":
{"category":"testCategory","created_at":"2011-09-27T05:41:42Z",
"size":5,"title":"testTitle2", "id":1,
"posts":[
{"number":1,"created_at":"2011-09-27T05:41:42Z",
"text":"text2","id":1,"topic_id":1},
{"number":0,"created_at":"2011-09-27T05:41:42Z",
"text":"sentence1","id":2,"story_id":1}
]
}
}
]
格式B:
[
{"category":"testCategory","created_at":"2011-09-27T05:41:42Z",
"size":5,"title":"testTitle2", "id":1,
"posts":[
{"number":1,"created_at":"2011-09-27T05:41:42Z",
"text":"text2","id":1,"topic_id":1},
{"number":0,"created_at":"2011-09-27T05:41:42Z",
"text":"sentence1","id":2,"story_id":1}
]
}
]
当我的restKit客户端获得格式B时,她很高兴,但当她获得格式A时,我收到以下错误:
... Could not find an object mapping for keyPath: '' ...
我的restKit配置位于底部。
所以我通过让我的rails 3.1服务器向她发送格式B JSON来修复它。
但是现在,restKit向服务器发送了一个格式为JSON的东西,他应该是他应该的。
为什么restKit不会收到格式A但是会发送格式A? 有没有办法让restKit发送格式B JSON? 或者,是否有办法让rails发送格式B并接收格式A?
我的restKit配置:
-(void)initRestKit{
RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURL:@"http://localhost:3000/"];
objectManager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@"WTF.sqlite"];
// Setup our object mappings
RKManagedObjectMapping* topicMapping = [RKManagedObjectMapping mappingForClass:[Topic class]];
storyMapping.primaryKeyAttribute = @"topicID";
storyMapping.setDefaultValueForMissingAttributes = YES;
[storyMapping mapKeyPathsToAttributes:
@"id", @"topicID",
....
@"created_at", @"dateCreated", nil];
RKManagedObjectMapping* postMapping = [RKManagedObjectMapping mappingForClass:[Post class]];
sentencesMapping.primaryKeyAttribute = @"postID";
[sentencesMapping mapKeyPathsToAttributes:
@"id", @"postID",
...
@"text", @"text" , nil];
//setup relationships
[storyMapping mapRelationship:@"posts" withMapping:postMapping];//topic -> (posts) -> post
// Register our mappings with the provider
[objectManager.mappingProvider setMapping:topicMapping forKeyPath:@"topic"];
[objectManager.mappingProvider setMapping:postMapping forKeyPath:@"post"];
// Set Up Router
[objectManager.router routeClass:[Topic class] toResourcePath:@"/topics.json" forMethod:RKRequestMethodPOST];
[objectManager.router routeClass:[Topic class] toResourcePath:@"/topics/(topicID).json"];
[objectManager.router routeClass:[Post class] toResourcePath:@"/topics/(topic.topicID)/posts.json" forMethod:RKRequestMethodPOST];
[objectManager.router routeClass:[Post class] toResourcePath:@"/topics/(topic.topicID)/(post.postID).json"];
}
-(void)sendTopic{
RKObjectManager *manager =[RKObjectManager sharedManager];
[manager postObject:self.topic delegate:nil block:^(RKObjectLoader *loader) {
RKObjectMapping* sendTopicMapping = [RKManagedObjectMapping mappingForClass:[Topic class]];
[sendTopicMapping mapKeyPathsToAttributes:
@"id", @"topicID",
....
@"title", @"title", nil];
RKManagedObjectMapping* postPostMapping = [RKManagedObjectMapping mappingForClass:[Post class]];
[postPostMapping mapKeyPathsToAttributes:
@"id", @"postID",
....
@"text", @"text" , nil];
[sendTopicMapping mapRelationship:@"posts" withMapping:postPostMapping];
[manager.mappingProvider setMapping:sendTopicMapping forKeyPath:@"topic"];
loader.serializationMapping = [sendTopicMapping inverseMapping];
}];
}
答案 0 :(得分:2)
由于你似乎控制了这个过程的两端,你也可以控制什么得到了sents。您提供的两个JSON代码段实际上是两个不同的数据结构。 (A)是一个包含两个对象的数组,每个对象包含许多成员元素。 (B)是一个数组,其中包含两个具有“患者”键和一个值的对象,该值是包含多个不同键/值对的另一个对象。
e.g。你的系统正在生成两种不同的数据结构,你的服务只期望这些结构中的一种 - 并且理所当然地不知道如何处理'坏'结构,即使它似乎包含正确的数据。
答案 1 :(得分:1)
如果有人有兴趣,我解决了它:
在rails中我改变了模型,所以它会像这样发送restKit客户端嵌套的json(格式A):class Topic < ActiveRecord::Base
has_many :posts
accepts_nested_attributes_for :posts
self.include_root_in_json = true
end
我将post方法属性嵌套为:
-(void)sendTopic{
RKObjectManager *manager =[RKObjectManager sharedManager];
[manager postObject:self.topic delegate:nil block:^(RKObjectLoader *loader) {
RKObjectMapping* sendTopicMapping = [RKManagedObjectMapping mappingForClass:[Topic class]];
[sendTopicMapping mapKeyPathsToAttributes:
@"topic[id]", @"topicID",
....
@"topic[title]", @"title", nil];
RKManagedObjectMapping* postPostMapping = [RKManagedObjectMapping mappingForClass:[Post class]];
[postPostMapping mapKeyPathsToAttributes:
@"post[id]", @"postID",
....
@"post[text]", @"text" , nil];
[sendTopicMapping mapRelationship:@"posts" withMapping:postPostMapping];
[manager.mappingProvider setMapping:sendTopicMapping forKeyPath:@"topic"];
loader.serializationMapping = [sendTopicMapping inverseMapping];
}];
}