Restkit: Post Json Array и ответ Map на управляемые объекты

Вот моя настройка: отправьте список объектов в Json на сервер и получите обновленные результаты, которые будут сопоставлены с основными данными и обновлены.

-- Почта Бодей --

{
    "memberId": "1000000",
    "contacts": [
        {
            "phoneNumber": "+12233333333",
            "firstName": "john",
            "lastName": "H"
        },
        {
            "phoneNumber": "+12244444444",
            "firstName": "mary",
            "lastName": "K"
        }
    ]
}

-- Опубликовать ответ --

{
    "contacts": [
        {
            "phoneNumber": "+12233333333",
            "firstName": "john",
            "lastName": "k",
            "isMember": "yes"

        },
        {
            "phoneNumber": "+12244444444",
            "firstName": "mary",
            "lastName": "k",
            "isMember": "no"
        }
    ]
}

Я нашел другую тему, в которой обсуждается очень похожее на мой случай. RestKit: как опубликовать массив объектов?

Это моя установка.

-- SHContact.h --

@interface SHContact : NSManagedObject {}

@property (nonatomic, strong) NSString* phoneNumber;
@property (nonatomic, strong) NSString* firstName;
@property (nonatomic, strong) NSString* lastName;
@property (nonatomic, strong) NSNumber* isMember;
@end

-- SHContactPost.m --

#import "SHContactPost.h"
@implementation SHContactPost
@synthesize contacts;
@synthesize memberId;
- (NSArray*)contacts {
    return <list-of-SHContact>;
}
- (NSString *)memberId {
    return @"my-member-id";
}
@end

-- Карта РК --

// Setup our object mappings for SHContact
RKManagedObjectMapping* contactMapping = 
       [RKManagedObjectMapping mappingForClass:[SHContact class]  
                          inManagedObjectStore:objectManager.objectStore];
contactMapping.primaryKeyAttribute = @"phoneNumber";
[contactMapping mapAttributes:@"phoneNumber", 
 @"firstName", @"lastName", @"isMember", nil];

[objectManager.mappingProvider setObjectMapping:contactMapping 
                                     forKeyPath:@"contacts"];

[[objectManager mappingProvider] 
                      setSerializationMapping:[contactMapping inverseMapping]
                                     forClass:[SHContact class]];

RKObjectMapping *cPostMapping = [RKObjectMapping 
                            mappingForClass:[SHContactPost class]];
[cPostMapping mapKeyPath:@"contacts" 
          toRelationship:@"contacts" 
             withMapping:contactMapping];
[cPostMapping mapAttributes:@"memberId", nil];
[objectManager.mappingProvider 
          setSerializationMapping:[cPostMapping inverseMapping] 
                         forClass:[SHContactPost class]];    
[objectManager.router routeClass:[SHContactPost class] 
                  toResourcePath:@"/contacts" 
                       forMethod:RKRequestMethodPOST];
objectManager.serializationMIMEType = RKMIMETypeJSON;

-- Отправить на сервер --

SHContactPost *post = [[SHContactPost alloc] init];
RKObjectManager* manager = [RKObjectManager sharedManager];
[manager postObject:post delegate:self];

Сообщение сервера и ответ УСПЕШНО. Однако Reskit не смог сопоставить результат со списком объектов SHContact. Это исключение. Я что-то упускаю?

restkit.network:RKObjectLoader.m:222 Encountered errors during mapping: 
Cannot map a collection of objects onto a non-mutable collection. 
Unexpected destination object type 'SHContactPost'

ОБНОВЛЕНИЕ: это то, что я изменил, чтобы оно работало на меня.

-- Карта РК --

// Setup our object mappings for SHContact
RKManagedObjectMapping* contactMapping = 
       [RKManagedObjectMapping mappingForClass:[SHContact class]  
                          inManagedObjectStore:objectManager.objectStore];
contactMapping.primaryKeyAttribute = @"phoneNumber";
[contactMapping mapAttributes:@"phoneNumber", 
 @"firstName", @"lastName", @"isMember", nil];
[objectManager.mappingProvider addObjectMapping:contactMapping];

-- Отправить на сервер --

SHContactPost *post = [[SHContactPost alloc] init];
RKObjectManager* manager = [RKObjectManager sharedManager];
RKObjectMapping* responseMapping = [manager.mappingProvider 
                            objectMappingForClass:[SHContact class]];
[manager postObject:post usingBlock:^(RKObjectLoader *loader) {
        loader.delegate = self;
        loader.targetObject = nil;
        responseMapping.rootKeyPath = @"contacts";
        loader.objectMapping = responseMapping;
 }];

loader.targetObject должен установить для него значение nil, иначе он не будет работать.


person angelokh    schedule 07.07.2012    source источник
comment
Вы можете опубликовать свой ответ как ответ и принять это :-)   -  person Ivan Vučica    schedule 31.05.2013