Несоответствие формата JSON - PullRequest
0 голосов
/ 27 сентября 2011

Есть два формата 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?Или, может быть, есть способ заставить рельсы отправлять формат 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 ]

2 голосов
/ 27 сентября 2011

Поскольку вы, кажется, контролируете оба конца процесса, у вас также есть контроль над тем, что получает отправления. Два предоставленных вами фрагмента JSON на самом деле представляют собой две РАЗНЫЕ структуры данных. (A) - это массив, который содержит два объекта, каждый из которых содержит несколько элементов-членов. (B) - это массив, который содержит два объекта с ключом «пациента» и значением, являющимся другим объектом, содержащим множество различных пар ключ / значение.

например. ваша система генерирует две разные структуры данных, и ваша служба ожидает только одну из этих структур - и по праву не знает, как справиться с «плохой», даже если она, похоже, содержит правильные данные.

1 голос
/ 27 сентября 2011

Я решил, если кому-то интересно:

в рельсах, я изменил мод, так что он отправит вложенный JSON (формат A) клиента restKit следующим образом:

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];
    }];
}
...