0

我遇到了两种 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 向服务器发送格式 A 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];
    }];
 }
4

2 回答 2

2

由于您似乎控制了流程的两端,因此您也可以控制发送的内容。您提供的两个 JSON 片段实际上是两个不同的数据结构。(A) 是一个包含两个对象的数组,每个对象包含许多成员元素。(B) 是一个数组,其中包含两个对象,这些对象具有一个“患者”键和一个值,该值是另一个包含大量不同键/值对的对象。

例如,您的系统正在生成两种不同的数据结构,而您的服务只需要其中一种结构——并且理所当然地不知道如何处理“坏”的结构,即使它似乎包含正确的数据。

于 2011-09-26T21:53:41.573 回答
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];
    }];
}
于 2011-09-27T09:29:07.803 回答