使用 AFNetworking 处理异步 POST json 请求
Posted
技术标签:
【中文标题】使用 AFNetworking 处理异步 POST json 请求【英文标题】:Using AFNetworking for asynchronous POST json requests 【发布时间】:2013-03-08 09:33:42 【问题描述】:我一直在尝试通过 AFNetworking 使用 POST json。经过一番研究,我终于得到了这个工作
- (IBAction)go:(id)sender
//Some POST
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@"https://www.test.com/"]];
[httpClient setParameterEncoding:AFJSONParameterEncoding];
NSMutableURLRequest *request = [httpClient requestWithMethod:@"POST"
path:@"https://www.test.com/user/login/"
parameters:@@"username":self.username.text, @"password":self.password.text];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
// Print the response body in text
NSDictionary *jsonDict = (NSDictionary *) responseObject;
BOOL *success = [[jsonDict objectForKey:@"success"] boolValue];
NSLog(@"Response: %@", [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]);
failure:^(AFHTTPRequestOperation *operation, NSError *error)
NSLog(@"Error: %@", error);
];
[operation start];
这对于演示来说很好,但现在我想最终使用 NSDirectory 来拆分我的 json 对象,所以我尝试做这样的事情,但是每当我点击按钮时我的应用程序就会崩溃
- (IBAction)go:(id)sender
//Some POST
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@"https://www.test.com/"]];
[httpClient setParameterEncoding:AFJSONParameterEncoding];
NSMutableURLRequest *request = [httpClient requestWithMethod:@"POST"
path:@"https://www.test.com/user/login/"
parameters:@@"username":self.username.text, @"password":self.password.text];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
// Print the response body in text
NSDictionary *jsonDict = (NSDictionary *) responseObject;
BOOL success = [[jsonDict objectForKey:@"success"] boolValue];
if (success)
NSLog(@"yes!!!");
else
NSString *reason = [jsonDict objectForKey:@"reason"];
NSLog(@"reason: %@",reason);
failure:^(AFHTTPRequestOperation *operation, NSError *error)
NSLog(@"Error: %@", error);
];
[operation start];
错误
2013-03-08 03:27:34.648 test[18253:c07] -[__NSCFData objectForKey:]: unrecognized selector sent to instance 0x888a6b0
2013-03-08 03:27:34.648 test[18253:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFData objectForKey:]: unrecognized selector sent to instance 0x888a6b0'
*** First throw call stack:
(0x1ce0012 0x111de7e 0x1d6b4bd 0x1ccfbbc 0x1ccf94e 0x24608 0x12e71 0x4a4453f 0x4a56014 0x4a467d5 0x1c86af5 0x1c85f44 0x1c85e1b 0x1c3a7e3 0x1c3a668 0x61ffc 0x21ad 0x20d5)
libc++abi.dylib: terminate called throwing an exception
【问题讨论】:
【参考方案1】:您使用的是AFHTTPRequestOperation
,而不是AFJSONRequestOperation
。
您也可以直接使用AFHttpClient
:
NSDictionary *parameter = @@"username":self.username.text, @"password":self.password.text;
[httpClient setParameterEncoding:AFJSONParameterEncoding];
[httpClient registerHTTPOperationClass:[AFJSONRequestOperation class]];
[httpClient postPath:@"api/v1/user/login/" parameters:parameter success:^(AFHTTPRequestOperation *operation, id responseObject)
// Print the response body in text
BOOL *success = [[responseObject objectForKey:@"success"] boolValue];
NSLog(@"Response: %@",responseObject);
failure:^(AFHTTPRequestOperation *operation, NSError *error)
[self handleConnectionError:error];
];
我还建议使用clientWithBaseURL:
方法创建一个仅创建AFHTTPClient
的一个实例。
【讨论】:
rckoenes,那是因为这是我能找到的唯一帖子示例。如果你不介意,你能详细说明一下吗?应该对现有代码进行哪些更改? 另请阅读github.com/AFNetworking/AFNetworking 上的文档,它确实解释了如何正确使用AFHTTPClient
。看看AFAppDotNetAPIClient
,这将为您提供如何使用AFHTTPClient
的一个很好的例子。
非常感谢 rckoenes。但什么是handleConnectionError?另外,我不需要[操作开始];不再?这个方法也是异步的吗?
handleConnectionError:
是我自己创建的方法,这样的方法将处理NSError
并向用户显示消息。是的,这些方法是异步的。
好的,这是有道理的。但我只是测试了这段代码。它给了我与上面的代码相同的错误【参考方案2】:
我试图发送 JSON 对象并取回 JSON 数据并解析它
NSURL *url = [NSURL URLWithString:@"https://MySite.com/"];
AFHTTPClient *httpClient = [[AFHTTPClient alloc]initWithBaseURL:url];
//[httpClient setParameterEncoding:AFJSONParameterEncoding];
//[httpClient registerHTTPOperationClass:[AFJSONRequestOperation class]];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
@"Ans", @"name",
@"29", @"age", nil];
NSMutableURLRequest *request = [httpClient requestWithMethod:@"POST"
path:@"/testJSONReturn.php"
parameters:params];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON)
NSLog(@"DATA: %@", [JSON valueForKeyPath:@"data"]);
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON)
NSLog(@"Request Failure Because %@",[error userInfo]);
];
[operation start];
可能有帮助
【讨论】:
【参考方案3】:使用 AFHTTPRequestOperationManager,您将添加您的请求管理器,在我的情况下,我已经使用 NSdictionnary 作为参数完成了一个 POST 方法
[manager GET:url parameters:parameters success:success failure:failure];
通过这一行,您可以选择您的方法 / GET 或 POST
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters= dic;
NSMutableString *url = [[NSMutableString alloc] init];
[url appendString: RootObj.root];
[url appendString:@"/yourURL/"];
manager.requestSerializer=[AFHTTPRequestSerializer serializer];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager POST:url parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject)
failure:^(AFHTTPRequestOperation *operation, NSError *error)
];
【讨论】:
请编辑您的答案,并解释这是如何解决问题的。【参考方案4】:另一种方法,使用 AFHTTPRequestOperation:
NSString* path = "http://www.test.com/file.php";
NSMutableURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:path]];
//request.HTTPMethod = @"GET";
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]initWithRequest:request];
//operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
NSLog(@"success: %@", operation.responseString);
failure:^(AFHTTPRequestOperation *operation, NSError *error)
NSLog(@"error: %@", operation.responseString);
];
[operation start];
【讨论】:
以上是关于使用 AFNetworking 处理异步 POST json 请求的主要内容,如果未能解决你的问题,请参考以下文章
AFNetworking 对用户名和密码参数的异步 POST 请求(Objective-C iOS)