RestKit Отображение объектов произвольных ключей - PullRequest
4 голосов
/ 17 ноября 2011

У меня есть JSON, который выглядит вот так:

 { 
  "key1":[ 
  { 
    "desc":"key1decs.", 
    "duration":50; 
  },{ 
    "desc":"", 
    "duration":90; 
  },{ 
    "desc":"Kurz vor...", 
    "duration":30; 
  } 
 ], 
 "key2":[ 
  { 
    "desc":"key2decs.", 
    "duration":50; 
  },{ 
    "desc":"blabla", 
    "duration":90; 
  } 
] 
} 

Я пытаюсь составить карту. Но я застрял из-за разных неизвестные / произвольные ключи. Я пытался картографировать без KVC, но, похоже, нет работать. Дает мне ошибку: Не удалось преобразовать значение в keyPath 'key1.desc'. Нет стратегии для преобразование из «__NSArrayI» в «NSString». и так далее для каждого приписывать. Я видел в Интернете, что отображение без KVC не поддерживает массивы как внутренние структуры. Плз, помогите. Какой здесь правильный подход?

EDIT: Entity:

@interface Sendung : NSObject

 @property (nonatomic, strong) NSString *description;
 @property (nonatomic, strong) NSNumber *duration;
 @property (nonatomic, strong) NSNumber *sendungkey;
@end;

Контроллер:

 RKObjectMapping* mapping = [RKObjectMapping mappingForClass:[Sendung class]];
 mapping.forceCollectionMapping = YES;
[mapping mapKeyOfNestedDictionaryToAttribute:@"sendungkey"];
[mapping mapKeyPath:@"(sendungkey).desc" toAttribute:@"description"];
[mapping mapKeyPath:@"(sendungkey).duration" toAttribute:@"duration"];
[[RKObjectManager sharedManager].mappingProvider addObjectMapping:mapping ];
 mapping = [[RKObjectManager sharedManager].mappingProvider objectMappingForClass:[Sendung class] ];
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:url objectMapping:mapping delegate:self];

Это то, что я получаю, когда результат NSlogin :( (ноль), (ноль), (ноль), (ноль), (ноль) )

1 Ответ

5 голосов
/ 17 ноября 2011

Я полагаю, что вы пропускаете один «уровень» своего отображения.Если вы внимательно присмотритесь к своему вводу, у вас есть словарь (key1), содержимое которого - не один 'Sendung', а массив таких объектов.Таким образом, вы не можете отобразить содержимое ключа key непосредственно на Sendung ivars, а не создать новый класс, например SendungResult.

@interface SendungResult : NSObject
    @property (nonatomic, strong) NSString *keyName;
    @property (nonatomic, strong) NSArray *sendungs;
@end

, и сопоставить содержимое ключа key1 с SendungResult sendungs массив с использованием сопоставления отношений, которое вы используете прямо сейчас.

РЕДАКТИРОВАТЬ: Я расширяю ответ следующим образом:

Как я уже говорил ранее, вы пытаетесь сопоставитьколлекция объектов в одном экземпляре, так что это не может работать.Вместо этого вам нужно создать SendungResult, который будет содержать массив Sendung экземпляров для одного ключа.Таким образом, в вашем примере вы получите два SendungResult экземпляра (один будет содержать три Sendung s - вложенные в "key1", а второй - только два, вложенные в "key2").Вы не можете отобразить такую ​​структуру в один класс, вы должны вложить их так же, как вложенный JSON.Класс Sendung в основном не изменился.

Теперь для отображения.Вам необходимо определить два сопоставления, одно сопоставит содержимое вашего корневого JSON с двумя SendungResult (по одному для каждого ключа), а второе сопоставление будет сопоставлять внутреннюю часть с отдельными Sendung экземплярами.

Мыначнем с внутреннего сопоставления.

RKObjectMapping *sendungMapping = [RKObjectMapping mappingForClass:[Sendung class]];
[sendungMapping mapKeyPath:@"desc" toAttribute:@"desc"];
[sendungMapping mapKeyPath:@"duration" toAttribute:@"duration"];
[[[RKObjectManager sharedManager] mappingProvider] addObjectMapping:sendungMapping];

Ничего особенного здесь нет, мы просто сопоставим траектории клавиш с вашими свойствами.Теперь для внешней части.

RKObjectMapping *resultMapping = [RKObjectMapping mappingForClass:[SendungResult class]];
[resultMapping setForceCollectionMapping:YES];
[resultMapping mapKeyOfNestedDictionaryToAttribute:@"keyName"];
[resultMapping mapKeyPath:@"(keyName)" toRelationship:@"sendungs" withMapping:sendungMapping];
[[[RKObjectManager sharedManager] mappingProvider] addObjectMapping:resultMapping];

Мы сообщаем RestKit сопоставить содержимое keyName keyPath со свойством sendungs, найденным в классе SendungResult, с отображением, определенным ранее.

Теперь мыможет извлекать данные

[[RKObjectManager sharedManager]  loadObjectsAtResourcePath:@"test.js" objectMapping:resultMapping delegate:self];

RestKit создаст два SendungResult экземпляра, каждый массив содержит внутренние Sendung классы (3 и 2 соответственно)

Примечание: Я настоятельно рекомендую вам прочитать RestKit Object Mapping документацию.Кроме того, JSONLint обнаружил, что ваш JSON является недействительным, мне пришлось удалить точку с запятой.Поэтому обязательно используйте действительный JSON.

...