JSON格式不一致

时间:2011-09-26 21:46:54

标签: restkit

我遇到了两种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];
    }];
 }

2 个答案:

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