Restkit嵌套映射有问题

我一直在试图创build一个login服务的请求,但我收到答复时有问题,我不知道我在做什么错。

这是我的代码:

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 

日志:

 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) 

问候。

您的JSON有效内容中有一个JSONstring。 RestKit不会很好玩。 理想情况下,你应该改变服务器。 否则,你将需要读取数据的string,并进行后处理…

该后处理可以通过创build和执行RKMappingOperation来使用RKMappingOperation ,但是如果可能的RKMappingOperation ,更改源JSON是更可取的,因为使用RKMappingOperation将会使得关系更难以pipe理。


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

您需要更正所有path模式和关键path(主要是path模式)。 此刻,您要求RestKit将所有映射应用于响应,并最终(如您所见)出现问题。 您使用path模式来限制哪些响应描述符应用于哪些响应。