2014-02-13 3 views
1

Как я могу сопоставить несколько объектов с одним JSON-объектом?Слияние объектов для RestKit

Вот мои два объекта

#import <RestKit/RestKit.h> 

@interface Account : NSObject 
@property NSInteger id; 
@property NSString* secret; 
@end 
@implementation Account @end 

@interface Entry : NSObject 
@property NSString* name; 
@end 
@implementation Entry @end 

И я хочу, чтобы отобразить эти объекты в следующем формате JSON:

/* Goal JSON: 
    { 
    "id":10, 
    "secret":"supersecret", 
    "eventName":"Hayooo" 
    } 
    */ 

Первая попытка была с помощью RKMapperOperation непосредственно:

void testMergeMap(){ 
    Account* account = [Account new]; 
    account.id = 10; 
    account.secret = @"supersecret"; 

    Entry* entry = [Entry new]; 
    entry.name = @"Hayooo"; 

    RKMapperOperation* mapper = [[RKMapperOperation alloc] 
           initWithRepresentation:@{@"account":account, @"entry":entry} mappingsDictionary:@{@"account.id": @"id", @"account.secret":@"secret", @"entry.name":@"eventName"}]; 
    [mapper start]; 
    RKMappingResult* result = mapper.mappingResult; 
    NSLog(@"%@", result.dictionary.description); 
} 

Но это сбой, не может действительно что-то сделать с ошибкой.

Итак, как мне это сделать?

EDIT

Я также попытался это

RKObjectManager* testSimpleMap(Account* account, Entry* entry){ 
    RKObjectMapping* map = [RKObjectMapping requestMapping]; 
    [map addAttributeMappingsFromDictionary: 
    @{@"account.id": @"id", 
     @"account.secret": @"secret", 
     @"entry.name":@"eventName"}]; 

    RKObjectManager* man = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://google.com"]]; 
    RKRequestDescriptor* requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:map objectClass:nil rootKeyPath:nil method:RKRequestMethodPOST]; 
    [man addRequestDescriptor:requestDescriptor]; 
    [man postObject:@{@"account":account, @"entry":entry} path:@"/" parameters:nil success:nil failure:nil]; 

    return man; 
} 

Но мы не можем создать requestDescriptors без класса, так что не работает. Но я думаю, что полезно знать, к чему я стремлюсь. Если бы это сработало, это было бы здорово!

+0

Не стесняйтесь редактировать, пожалуйста, не редактируйте таким образом, чтобы он больше не копировался и не использовался в редакторе. Я позаботился о том, чтобы сделать его самодостаточным, не разрушайте это. – Nick

ответ

0

mappingsDictionary: не должен быть словарем простых строковых ключей и значений. Ключи должны быть ключевыми путями к отображаемым элементам, а значения должны быть RKMapping экземпляров, которые описывают, как сопоставить данные, найденные на ключевом пути.

В общем, если вы только начинаете, я не буду использовать RKMapperOperation напрямую. Я бы посмотрел на использование RKObjectManager. Он абстрагирует вас от внутренних деталей, подобных этому.

Если вы хотите продолжить работу с тобой, то посмотрите пример in the docs.

+0

Я не хочу продолжать использовать RKMapperOperation напрямую, и я использую RKObjectManager в своем «реальном» приложении (это всего лишь небольшая тестовая запись). Я просто видел этот класс в документах и ​​думал, что стоит попробовать. Как это сделать с помощью экземпляров RKMapping? – Nick

+0

Вы использовали 'RKObjectMapping' раньше? Если у вас есть менеджер объектов, то я так думаю. Просто сопоставьте имена свойств с именами ключей JSON. – Wain

+0

Но я не могу понять, как создать сопоставление, чтобы я мог объединить объект Account и Entry в один запрос. Это проблема. TUTORIAL.md прекрасно показывает, как получить 2 объекта из одного ответа с отношениями, но как отправить 2 объекта в 1 запрос? – Nick

0

Создание третьего объекта, который моделирует отношения, работает, но я не считаю его достаточно элегантным.

@interface Both : NSObject 
@property Account* account; 
@property Entry* entry; 
@end 
@implementation Both @end 

RKObjectManager* testRelationMap(Account* account, Entry* entry){ 
    /* Goal JSON: 
    { 
     "user":{ 
      "id":10, 
      "secret":"supersecret", 
     }, 
     "entry":{ 
      "name":"Hayooo" 
     } 
    } 
    */ 

    Both* both = [Both new]; 
    both.account = account; 
    both.entry = entry; 

    RKObjectMapping* accountMap = [RKObjectMapping requestMapping]; 
    [accountMap addAttributeMappingsFromArray:@[@"id", @"secret"]]; 

    RKObjectMapping* entryMap = [RKObjectMapping requestMapping]; 
    [entryMap addAttributeMappingsFromArray:@[@"name"]]; 

    RKObjectMapping* relationMap = [RKObjectMapping requestMapping]; 
    [relationMap addRelationshipMappingWithSourceKeyPath:@"account" mapping:accountMap]; 
    [relationMap addRelationshipMappingWithSourceKeyPath:@"entry" mapping:entryMap]; 

    RKObjectManager* man = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://google.com"]]; 
    RKRequestDescriptor* requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:relationMap objectClass:[Both class] rootKeyPath:nil method:RKRequestMethodPOST]; 
    [man addRequestDescriptor:requestDescriptor]; 
    [man postObject:both path:@"/" parameters:nil success:nil failure:nil]; 
    return man; 
} 

Здесь необходимо много кода, но это решение.

Смежные вопросы