我是IOS和RestKit的新手,无法弄清楚如何执行以下操作:
1. a simple POST to a webservice
A) with an object payload
B) Have RestKit Auto Serialize the obj c object into Json
2. Receive the Response
A) Parse response and extract only certain fields and load into obj c object
我的设置如下:
来自webservice的Json回复:
{
"user": {
"id":0,
"email":"String",
},
"errorCode": 0
}
来自Web服务的响应对象,对象:
@interface CreateAccountResponse : NSObject
@property (nonatomic, copy) NSString *id;
@property (nonatomic, copy) NSString *email;
@property (nonatomic) NSInteger *errorCode;
@end
obj C中的请求对象:
@interface CreateAccountRequestModel : NSObject
@property (nonatomic, copy) NSString *email;
@property (nonatomic, copy) NSString *password;
@property (nonatomic, copy) NSString *first_name;
@property (nonatomic, copy) NSString *last_name;
@end
Webservice希望在POST请求中使用这个Json:
{
"email":"String",
"password":"String",
"first_name":"String",
"last_name":"String"
}
网址为:www.hostname.com/api/AccountManager/createAccount
,它只接受POST请求。
我尝试过:
-(void)SendCreateAccountRequest:(CreateAccountRequestModel*)createActModel
{
NSString *createAccountUrl = @"www.hostname.com/api/AccountManager/createAccount";
NSLog(@"SendCreateAccountRequest");
RKObjectMapping* articleMapping = [RKObjectMapping mappingForClass: [CreateAccountResponse class]];
[articleMapping addAttributeMappingsFromDictionary:@{
@"id": @"user.id",
@"email": @"user.email",
@"errorCode": @"errorCode"
}];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:articleMapping method:RKRequestMethodAny pathPattern:nil keyPath:@"createAccount" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
NSURL *URL = [NSURL URLWithString:createAccountUrl];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
RKObjectRequestOperation *objectRequestOperation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[ responseDescriptor ]];
[objectRequestOperation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult)
{
RKLogInfo(@"Successful Response: %@", mappingResult.array);
}
failure:^(RKObjectRequestOperation *operation, NSError *error)
{
RKLogError(@"Operation failed with error: %@", error);
}];
[objectRequestOperation start];
我知道我没有正确地将响应从webservice映射到对象,而我没有正确创建POST请求。就像我说我是新人一样,所以你提供的细节越多越好:)
答案 0 :(得分:1)
这应该发布一个帖子而不需要第三方库。一旦你开始工作,你可以将getter放在同一个类中并将其称为RestKit,或者使用工作示例来调试RestKit问题。 (我的偏好是前者)。
+ (void)postTo:(NSString *)urlString params:(NSDictionary *)params completion:(void (^)(id, NSError *))completion {
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
if (params.count) {
NSMutableArray *paramArray = [NSMutableArray array];
for (NSString *key in [params allKeys]) {
NSString *encodedKey = [key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *encodedValue = [params[key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *encodedPair = [[encodedKey stringByAppendingString:@"="] stringByAppendingString:encodedValue];
[paramArray addObject:encodedPair];
}
NSString *paramString = [paramArray componentsJoinedByString:@"&"];
NSData *data = [paramString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
[request setHTTPBody:data];
[request setValue:[NSString stringWithFormat:@"%d", [data length]] forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
}
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (!error && httpResponse.statusCode < 400) {
NSError *parseError;
id parse = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&parseError];
if (!parseError) {
completion(parse, nil);
} else {
NSLog(@"parse error %@", parseError);
completion(nil, parseError);
}
} else {
NSLog(@"http status %d, error %@", httpResponse.statusCode, error);
completion(nil, error);
}
}];
}
这样称呼:
NSString *urlString = @"http://www.hostname.com/api/AccountManager/createAccount";
NSDictionary *params = @{ @"email": @"user.email@gmail.com" /* and so on */ };
// assume the method above is a class method in "ThePostingClass"
[ThePostingClass postTo:urlString params:params completion:^(id result, NSError *error) {
if (!error) {
NSLog(@"%@", result);
} else {
NSLog(@"%@", error);
}
}];
Getter更容易,将setHttpMethod更改为@“GET”,并可选择通过将paramString作为查询字符串附加来移动params。
答案 1 :(得分:1)
keyPath:@"createAccount"
似乎是错误的,因为您的JSON不包含此密钥(因此它应该是keyPath:nil
)。实际上应该将其设置为路径模式(pathPattern:@"createAccount"
)。
您应该使用RKObjectManager
的实例来创建和发送请求 - 这样您就可以轻松地序列化要发送的请求对象。要启用此功能,您需要创建一个请求描述符,其中包含对象中键的映射(名称不会更改,因此它是一个简单的映射)。
使用RKObjectManager
时,用它注册请求和响应描述符,然后只注册GET / POST对象。 RKObjectManager
将根据您在请求中指定的路径确定应使用哪些请求和响应映射。
创建RKObjectManager
时,请使用www.hostname.com/api/AccountManager
的基本网址。
最后,要发送JSON,您需要在requestSerializationMIMEType
上设置RKObjectManager
(因为它不默认为JSON)。
答案 2 :(得分:1)
用户对象
@interface User : NSObject
@property (nonatomic, copy) NSString *id;
@property (nonatomic, copy) NSString *email;
@property (nonatomic, copy) NSString *password;
@property (nonatomic, copy) NSString *first_name;
@property (nonatomic, copy) NSString *last_name;
@end
POST http://www.hostname.com/api/AccountManager/createAccount
回应JSON
{
"id":0,
"email":"String",
}
在服务器上创建
- (void)createUserOnServer:(User *)user
{
RKObjectMapping *responseMapping = [RKObjectMapping mappingForClass:[User class]];
[responseMapping addAttributeMappingsFromArray:@[@"id",@"email"]];
NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);
RKResponseDescriptor *userResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:responseMapping method:RKRequestMethodAny pathPattern:@"/createAccount" keyPath:@"article" statusCodes:statusCodes];
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping]; // objectClass == NSMutableDictionary
[requestMapping addAttributeMappingsFromArray:@[@"email", @"password", @"first_name", @"last_name"]];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping objectClass:[Article class] rootKeyPath:nil method:RKRequestMethodAny];
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://www.hostname.com/api/AccountManager"];
[manager addRequestDescriptor:requestDescriptor];
[manager addResponseDescriptor:articleDescriptor];
[manager postObject:user path:@"/createAccount" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(@"Create User Success");
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"Create User Error: %@", error);
}];
}
PS:你最好完全阅读Restkit的README !!
PS2:HTTP statusCode的错误代码更好