遇到Restkit嵌套映射问题

时间:2014-03-07 18:07:33

标签: ios restkit restkit-0.20

我一直在尝试创建一个登录服务的请求,但是我收到响应时遇到了问题,而且我不知道我做错了什么。

这是我的代码:

AppDelagate

/* LOGIN RESPONSE */
    RKObjectMapping *userMapping = [RKObjectMapping mappingForClass:[UserMapping class]];
    [userMapping addAttributeMappingsFromDictionary:@{ @"_id":@"_id", @"name": @"name", @"lastname": @"lastname", @"username": @"username", @"password": @"password", @"repeatPassword": @"repeatPassword", @"age": @"age", @"gender": @"gender", @"photo": @"photo"}];

    RKObjectMapping *loginResponseMapping = [RKObjectMapping mappingForClass:[LoginResponse class]];
    [loginResponseMapping addAttributeMappingsFromArray:@[ @"code", @"message" ]];
    [loginResponseMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"data" toKeyPath:@"data" withMapping:userMapping]];

    RKResponseDescriptor *loginResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:loginResponseMapping method:RKRequestMethodPOST pathPattern:nil keyPath:nil statusCodes:[NSIndexSet indexSetWithIndex:200]];

    [manager addResponseDescriptor:baseResponseDescriptor];
    [manager addRequestDescriptor:loginRequestDescriptor];
    [manager addResponseDescriptor:loginResponseDescriptor];
    [manager addRequestDescriptor:signupRequestDescriptor];

    /* SERIALIZATION TYPE */
    [manager setRequestSerializationMIMEType:RKMIMETypeJSON];

LoginResponse类

@interface LoginResponse : NSObject

@property (nonatomic, strong) NSNumber *code;
@property (nonatomic, strong) NSString *message;
@property (nonatomic, strong) UserMapping *data;

@end

UserMapping类

@interface UserMapping : NSObject

@property (nonatomic, strong) NSString *_id;
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *lastname;
@property (nonatomic, strong) NSString *age;
@property (nonatomic, strong) NSString *gender;
@property (nonatomic, strong) NSString *username;
@property (nonatomic, strong) NSString *password;
@property (nonatomic, strong) NSString *repeatPassword;
@property (nonatomic, strong) NSString *photo;

@end

LOG:

2014-03-07 14:56:19.439 Shoopi[8149:a0b] D restkit.object_mapping:RKMappingOperation.m:952 Starting mapping operation...
2014-03-07 14:56:19.440 Shoopi[8149:a0b] T restkit.object_mapping:RKMappingOperation.m:953 Performing mapping operation: <RKMappingOperation 0xbb711f0> for '__NSDictionaryM' object. Mapping values from object <LoginRequest: 0xbbcfb20> ((null)) to object {
} with object mapping (null)
2014-03-07 14:56:19.441 Shoopi[8149:a0b] T restkit.object_mapping:RKMappingOperation.m:550 Mapping attribute value keyPath 'username' to 'username'
2014-03-07 14:56:19.442 Shoopi[8149:410b] D restkit.object_mapping:RKPropertyInspector.m:130 Cached property inspection for Class 'NSMutableDictionary': {
    fileHFSFlags =     {
        isPrimitive = 1;
        keyValueCodingClass = NSNumber;
        name = fileHFSFlags;
    };
    fileHFSResourceForkSize =     {
        isPrimitive = 1;
        keyValueCodingClass = NSNumber;
        name = fileHFSResourceForkSize;
    };
}
2014-03-07 14:56:19.442 Shoopi[8149:a0b] T restkit.object_mapping:RKMappingOperation.m:572 Mapped attribute value from keyPath 'username' to 'username'. Value: test@test.cl
2014-03-07 14:56:19.443 Shoopi[8149:a0b] T restkit.object_mapping:RKMappingOperation.m:550 Mapping attribute value keyPath 'password' to 'password'
2014-03-07 14:56:19.443 Shoopi[8149:410b] D restkit.object_mapping:RKPropertyInspector.m:130 Cached property inspection for Class 'LoginRequest': {
    password =     {
        isPrimitive = 0;
        keyValueCodingClass = NSString;
        name = password;
    };
    username =     {
        isPrimitive = 0;
        keyValueCodingClass = NSString;
        name = username;
    };
}
2014-03-07 14:56:19.445 Shoopi[8149:a0b] T restkit.object_mapping:RKMappingOperation.m:572 Mapped attribute value from keyPath 'password' to 'password'. Value: 1234
2014-03-07 14:56:19.446 Shoopi[8149:a0b] D restkit.object_mapping:RKMappingOperation.m:1021 Finished mapping operation successfully...
2014-03-07 14:56:19.450 Shoopi[8149:a0b] AJUA !
2014-03-07 14:56:19.456 Shoopi[8149:a0b] T restkit.network:RKObjectRequestOperation.m:178 POST 'http://shoppi-services.herokuapp.com/public/login':
request.headers={
    Accept = "application/json";
    "Accept-Language" = "en;q=1, fr;q=0.9, de;q=0.8, zh-Hans;q=0.7, zh-Hant;q=0.6, ja;q=0.5";
    "Content-Type" = "application/json; charset=utf-8";
    "User-Agent" = "Shoopi/1.0 (iPhone Simulator; iOS 7.0; Scale/2.00)";
}
request.body={"username":"test@test.cl","password":"1234"}
2014-03-07 14:56:19.981 Shoopi[8149:410b] D restkit.object_mapping:RKMapperOperation.m:377 Executing mapping operation for representation: {
    code = 0;
    data = "{\"_id\":\"5319459fe6b6558526000001\",\"age\":\"19\",\"gender\":\"female\",\"lastname\":\"test\",\"name\":\"test\",\"password\":\"1234\",\"photo\":null,\"repeatPassword\":\"1234\",\"username\":\"test@test.cl\"}";
    message = Success;
}
 and targetObject: (null)
2014-03-07 14:56:19.982 Shoopi[8149:410b] T restkit.object_mapping:RKMapperOperation.m:320 Examining keyPath '' for mappable content...
2014-03-07 14:56:19.982 Shoopi[8149:410b] D restkit.object_mapping:RKMapperOperation.m:300 Found mappable data at keyPath '': {
    code = 0;
    data = "{\"_id\":\"5319459fe6b6558526000001\",\"age\":\"19\",\"gender\":\"female\",\"lastname\":\"test\",\"name\":\"test\",\"password\":\"1234\",\"photo\":null,\"repeatPassword\":\"1234\",\"username\":\"test@test.cl\"}";
    message = Success;
}
2014-03-07 14:56:19.983 Shoopi[8149:410b] D restkit.object_mapping:RKMapperOperation.m:231 Asked to map source object {
    code = 0;
    data = "{\"_id\":\"5319459fe6b6558526000001\",\"age\":\"19\",\"gender\":\"female\",\"lastname\":\"test\",\"name\":\"test\",\"password\":\"1234\",\"photo\":null,\"repeatPassword\":\"1234\",\"username\":\"test@test.cl\"}";
    message = Success;
} with mapping <RKObjectMapping:0x8c9e1e0 objectClass=BaseModel propertyMappings=(
    "<RKAttributeMapping: 0x8cadf20 code => code>",
    "<RKAttributeMapping: 0x8ca6920 message => message>"
)>
2014-03-07 14:56:19.984 Shoopi[8149:410b] D restkit.object_mapping:RKMappingOperation.m:952 Starting mapping operation...
2014-03-07 14:56:19.984 Shoopi[8149:410b] T restkit.object_mapping:RKMappingOperation.m:953 Performing mapping operation: <RKMappingOperation 0xbb6db80> for 'BaseModel' object. Mapping values from object {
    code = 0;
    data = "{\"_id\":\"5319459fe6b6558526000001\",\"age\":\"19\",\"gender\":\"female\",\"lastname\":\"test\",\"name\":\"test\",\"password\":\"1234\",\"photo\":null,\"repeatPassword\":\"1234\",\"username\":\"test@test.cl\"}";
    message = Success;
} to object <BaseModel: 0xbbf2b80> with object mapping (null)
2014-03-07 14:56:19.985 Shoopi[8149:410b] T restkit.object_mapping:RKMappingOperation.m:550 Mapping attribute value keyPath 'code' to 'code'
2014-03-07 14:56:19.986 Shoopi[8149:410b] T restkit.object_mapping:RKMappingOperation.m:572 Mapped attribute value from keyPath 'code' to 'code'. Value: 0
2014-03-07 14:56:19.986 Shoopi[8149:1007] D restkit.object_mapping:RKPropertyInspector.m:130 Cached property inspection for Class 'BaseModel': {
    code =     {
        isPrimitive = 0;
        keyValueCodingClass = NSNumber;
        name = code;
    };
    message =     {
        isPrimitive = 0;
        keyValueCodingClass = NSString;
        name = message;
    };
}
2014-03-07 14:56:19.986 Shoopi[8149:410b] T restkit.object_mapping:RKMappingOperation.m:550 Mapping attribute value keyPath 'message' to 'message'
2014-03-07 14:56:19.986 Shoopi[8149:410b] T restkit.object_mapping:RKMappingOperation.m:572 Mapped attribute value from keyPath 'message' to 'message'. Value: Success
2014-03-07 14:56:19.987 Shoopi[8149:410b] D restkit.object_mapping:RKMappingOperation.m:1021 Finished mapping operation successfully...
2014-03-07 14:56:19.987 Shoopi[8149:410b] T restkit.object_mapping:RKMapperOperation.m:320 Examining keyPath '<null>' for mappable content...
2014-03-07 14:56:19.988 Shoopi[8149:410b] D restkit.object_mapping:RKMapperOperation.m:300 Found mappable data at keyPath '<null>': {
    code = 0;
    data = "{\"_id\":\"5319459fe6b6558526000001\",\"age\":\"19\",\"gender\":\"female\",\"lastname\":\"test\",\"name\":\"test\",\"password\":\"1234\",\"photo\":null,\"repeatPassword\":\"1234\",\"username\":\"test@test.cl\"}";
    message = Success;
}
2014-03-07 14:56:19.989 Shoopi[8149:410b] D restkit.object_mapping:RKMapperOperation.m:231 Asked to map source object {
    code = 0;
    data = "{\"_id\":\"5319459fe6b6558526000001\",\"age\":\"19\",\"gender\":\"female\",\"lastname\":\"test\",\"name\":\"test\",\"password\":\"1234\",\"photo\":null,\"repeatPassword\":\"1234\",\"username\":\"test@test.cl\"}";
    message = Success;
} with mapping <RKObjectMapping:0x8caafa0 objectClass=LoginResponse propertyMappings=(
    "<RKAttributeMapping: 0x8cab020 code => code>",
    "<RKAttributeMapping: 0x8cab030 message => message>",
    "<RKRelationshipMapping: 0x8cab240 data => data>"
)>
2014-03-07 14:56:19.989 Shoopi[8149:410b] D restkit.object_mapping:RKMappingOperation.m:952 Starting mapping operation...
2014-03-07 14:56:19.990 Shoopi[8149:410b] T restkit.object_mapping:RKMappingOperation.m:953 Performing mapping operation: <RKMappingOperation 0x8ccb570> for 'LoginResponse' object. Mapping values from object {
    code = 0;
    data = "{\"_id\":\"5319459fe6b6558526000001\",\"age\":\"19\",\"gender\":\"female\",\"lastname\":\"test\",\"name\":\"test\",\"password\":\"1234\",\"photo\":null,\"repeatPassword\":\"1234\",\"username\":\"test@test.cl\"}";
    message = Success;
} to object <LoginResponse: 0xb9adc50> with object mapping (null)
2014-03-07 14:56:19.990 Shoopi[8149:410b] T restkit.object_mapping:RKMappingOperation.m:550 Mapping attribute value keyPath 'code' to 'code'
2014-03-07 14:56:19.990 Shoopi[8149:410b] T restkit.object_mapping:RKMappingOperation.m:572 Mapped attribute value from keyPath 'code' to 'code'. Value: 0
2014-03-07 14:56:19.990 Shoopi[8149:1007] D restkit.object_mapping:RKPropertyInspector.m:130 Cached property inspection for Class 'LoginResponse': {
    code =     {
        isPrimitive = 0;
        keyValueCodingClass = NSNumber;
        name = code;
    };
    data =     {
        isPrimitive = 0;
        keyValueCodingClass = UserMapping;
        name = data;
    };
    message =     {
        isPrimitive = 0;
        keyValueCodingClass = NSString;
        name = message;
    };
}
2014-03-07 14:56:19.991 Shoopi[8149:410b] T restkit.object_mapping:RKMappingOperation.m:550 Mapping attribute value keyPath 'message' to 'message'
2014-03-07 14:56:19.991 Shoopi[8149:410b] T restkit.object_mapping:RKMappingOperation.m:572 Mapped attribute value from keyPath 'message' to 'message'. Value: Success
2014-03-07 14:56:19.992 Shoopi[8149:410b] D restkit.object_mapping:RKMappingOperation.m:683 Mapping one to one relationship value at keyPath 'data' to 'data'
2014-03-07 14:56:19.992 Shoopi[8149:410b] T restkit.object_mapping:RKMappingOperation.m:641 Performing nested object mapping using mapping <RKRelationshipMapping: 0x8cab240 data => data> for data: {"_id":"5319459fe6b6558526000001","age":"19","gender":"female","lastname":"test","name":"test","password":"1234","photo":null,"repeatPassword":"1234","username":"test@test.cl"}
2014-03-07 14:56:19.993 Shoopi[8149:410b] D restkit.object_mapping:RKMappingOperation.m:952 Starting mapping operation...
2014-03-07 14:56:19.993 Shoopi[8149:410b] T restkit.object_mapping:RKMappingOperation.m:953 Performing mapping operation: <RKMappingOperation 0x8ccc990> for 'UserMapping' object. Mapping values from object {"_id":"5319459fe6b6558526000001","age":"19","gender":"female","lastname":"test","name":"test","password":"1234","photo":null,"repeatPassword":"1234","username":"test@test.cl"} ({
    HTTP =     {
        request =         {
            URL = "http://shoppi-services.herokuapp.com/public/login";
            headers =             {
                Accept = "application/json";
                "Accept-Language" = "en;q=1, fr;q=0.9, de;q=0.8, zh-Hans;q=0.7, zh-Hant;q=0.6, ja;q=0.5";
                "Content-Type" = "application/json; charset=utf-8";
                "User-Agent" = "Shoopi/1.0 (iPhone Simulator; iOS 7.0; Scale/2.00)";
            };
            method = POST;
        };
        response =         {
            URL = "http://shoppi-services.herokuapp.com/public/login";
            headers =             {
                Connection = "keep-alive";
                "Content-Length" = 250;
                "Content-Type" = "application/json;charset=utf-8";
                Date = "Fri, 07 Mar 2014 17:56:19 GMT";
                Server = "WEBrick/1.3.1 (Ruby/2.1.0/2013-12-25)";
                "Set-Cookie" = "SHOPPI-TOKEN=BAh7B0kiD3Nlc3Npb25faWQGOgZFVEkiRTZkY2FmNDQ2NGU1MDNhYjJmYzdl%0AMDA3ZDczOGQ0OTQ0NTI4YmFmMTE0NTY5OTU0YmFjMTE3NWNhYjE4OTFkMjAG%0AOwBGSSIUc2luYXRyYS5zZXNzaW9uBjsAVFQ%3D%0A--dafa7a330f49e7c69ca1fd8d0768a889dd2345d2; path=/; expires=Fri, 07 Mar 2014 18:56:19 -0000; HttpOnly";
                Via = "1.0 proxy2.taisagroup.com (squid)";
                "X-Cache" = "MISS from proxy2.taisagroup.com";
                "X-Cache-Lookup" = "MISS from proxy2.taisagroup.com:3128";
                "X-Content-Type-Options" = nosniff;
            };
        };
    };
    mapping =     {
        collectionIndex = "<null>";
        rootKeyPath = "<null>";
    };
}) to object <UserMapping: 0x8ccb720> with object mapping (null)
2014-03-07 14:56:20.045 Shoopi[8149:410b] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFString 0xbb6e580> valueForUndefinedKey:]: this class is not key value coding-compliant for the key _id.'
*** First throw call stack:
(
    0   CoreFoundation                      0x024e95e4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x0226c8b6 objc_exception_throw + 44
    2   CoreFoundation                      0x025796a1 -[NSException raise] + 17
    3   Foundation                          0x01f2db0a -[NSObject(NSKeyValueCoding) valueForUndefinedKey:] + 282
    4   Foundation                          0x01e9ab61 _NSGetUsingKeyValueGetter + 81
    5   Foundation                          0x01e9a19b -[NSObject(NSKeyValueCoding) valueForKey:] + 260
    6   Foundation                          0x01eb9c9a -[NSObject(NSKeyValueCoding) valueForKeyPath:] + 409
    7   Shoopi                              0x000d2571 -[RKMappingSourceObject valueForKeyPath:] + 833
    8   Shoopi                              0x000d7b87 -[RKMappingOperation applyAttributeMappings:] + 1671
    9   Shoopi                              0x000df57e -[RKMappingOperation main] + 4062
    10  Foundation                          0x01f41a69 -[__NSOperationInternal _start:] + 671
    11  Foundation                          0x01ebe798 -[NSOperation start] + 83
    12  Shoopi                              0x000d8a0a -[RKMappingOperation mapNestedObject:toObject:withRelationshipMapping:metadata:] + 1706
    13  Shoopi                              0x000d9655 -[RKMappingOperation mapOneToOneRelationshipWithValue:mapping:] + 1477
    14  Shoopi                              0x000dd2e6 -[RKMappingOperation applyRelationshipMappings] + 6870
    15  Shoopi                              0x000df620 -[RKMappingOperation main] + 4224
    16  Foundation                          0x01f41a69 -[__NSOperationInternal _start:] + 671
    17  Foundation                          0x01ebe798 -[NSOperation start] + 83
    18  Shoopi                              0x000ccbe5 -[RKMapperOperation mapRepresentation:toObject:atKeyPath:usingMapping:metadata:] + 1957
    19  Shoopi                              0x000cb460 -[RKMapperOperation mapRepresentation:atKeyPath:usingMapping:] + 1904
    20  Shoopi                              0x000cdddd -[RKMapperOperation mapRepresentationOrRepresentations:atKeyPath:usingMapping:] + 829
    21  Shoopi                              0x000ce732 -[RKMapperOperation mapSourceRepresentationWithMappingsDictionary:] + 2210
    22  Shoopi                              0x000cf0fb -[RKMapperOperation main] + 1403
    23  Foundation                          0x01f41a69 -[__NSOperationInternal _start:] + 671
    24  Foundation                          0x01ebe798 -[NSOperation start] + 83
    25  Shoopi                              0x0011f7ba -[RKObjectResponseMapperOperation performMappingWithObject:error:] + 1354
    26  Shoopi                              0x0011d7b3 -[RKResponseMapperOperation main] + 2371
    27  Foundation                          0x01f41a69 -[__NSOperationInternal _start:] + 671
    28  Foundation                          0x01ebe798 -[NSOperation start] + 83
    29  Foundation                          0x01f43d34 __NSOQSchedule_f + 62
    30  libdispatch.dylib                   0x0310f4b0 _dispatch_client_callout + 14
    31  libdispatch.dylib                   0x030fd088 _dispatch_queue_drain + 450
    32  libdispatch.dylib                   0x030fce85 _dispatch_queue_invoke + 126
    33  libdispatch.dylib                   0x030fde25 _dispatch_root_queue_drain + 83
    34  libdispatch.dylib                   0x030fe13d _dispatch_worker_thread2 + 39
    35  libsystem_c.dylib                   0x03427e72 _pthread_wqthread + 441
    36  libsystem_c.dylib                   0x0340fd2a start_wqthread + 30
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

问候。

1 个答案:

答案 0 :(得分:1)

您的JSON有效内容中有一个JSON字符串。 RestKit不会那么好玩。理想情况下,您应该更改服务器。否则,您需要以字符串形式读取数据并对其进行后处理...

后期处理可以通过创建和执行RKMappingOperation来使用RestKit,但是如果可能的话,更改源JSON是更可取的,因为使用RKMappingOperation会使关系更难管理。


最初的错误答案,但无论如何重要:

您需要更正所有路径模式和密钥路径(主要是路径模式)。目前,您要求RestKit将所有映射应用于响应,并最终(如您所见)会出现问题。您可以使用路径模式来限制将哪些响应描述符应用于哪些响应。