问题
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.
Here's my code:
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 class
@interface LoginResponse : NSObject
@property (nonatomic, strong) NSNumber *code;
@property (nonatomic, strong) NSString *message;
@property (nonatomic, strong) UserMapping *data;
@end
UserMapping class
@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)
Regards.
回答1:
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...
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:
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.
来源:https://stackoverflow.com/questions/22257516/having-problems-with-restkit-nested-mappings