Restkit 嵌套映射有问题 [英] Having problems with Restkit nested mappings
问题描述
我一直在尝试向登录服务创建请求,但在接收响应时遇到问题,而且我不知道自己做错了什么.
I've been trying to create a request to a login service, but i'm having problems when receiving the response, and i don't know what i'm doing wrong.
这是我的代码:
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];
登录响应类
@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 负载中有一个 JSON 字符串.RestKit 不会很好地玩这个.理想情况下,您应该更改服务器.否则,您需要将数据作为字符串读取并对其进行后处理...
You have a JSON string inside your JSON payload. RestKit isn't going to play nice with that. Ideally you should change the server. Otherwise you would need to read data in as the string it is and post-process it...
该后处理可以通过创建和执行 RKMappingOperation
来使用 RestKit,但如果可能,更改源 JSON 更可取,因为使用 RKMappingOperation
会使关系更难管理.
That post processing could use RestKit by creating and executing a RKMappingOperation
, but changing the source JSON is far preferable if possible as using RKMappingOperation
will make relationships harder to manage.
最初的错误答案,但无论如何都很重要:
Initial wrong answer, but important anyway:
您需要更正所有路径模式和关键路径(主要是路径模式).目前,您要求 RestKit 将所有映射应用于响应,最终(如您所见)会出现问题.您可以使用路径模式来限制将哪些响应描述符应用于哪些响应.
You need to correct all of your path patterns and keypaths (mostly path patterns). At the moment you're asking RestKit to apply all mappings to responses and eventually (as you see) something will go wrong. You use path patterns to limit which response descriptors are applied to which responses.
这篇关于Restkit 嵌套映射有问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!