NSURLRequest : 发布数据并读取发布的页面 [英] NSURLRequest : Post data and read the posted page
问题描述
在 iOS(当前目标 5.0,Base SDK 5.1)中,如何向服务器发送 post 请求,然后读取页面内容.例如,页面采用用户名和密码,然后回显 true 或 false.这只是为了更好地理解 NSURLRequest.
In iOS (current target 5.0, Base SDK 5.1) how can I send a post request to a server, and then read the contents of the page. For example, the page takes a username and password, and then echos true or false. This is just for a better understanding of NSURLRequest.
提前致谢!
推荐答案
先说几件事
- 决定您希望如何对数据进行编码 - JSON 或 url 编码是一个好的开始.
- 决定一个返回值——它是 1、TRUE 还是 0、FALSE,甚至是 YES/非 nil 什么都没有/nil.
- 阅读URL 加载系统,它是您的朋友.
- Decide how you want to encode your data - JSON or url-encoding are a good start.
- Decide upon a return value - will it be 1, TRUE or 0, FALSE, or even YES/non-nil nothing/nil.
- Read up on the URL Loading System, it's your friend.
旨在使您的所有 url 连接异步,以便您的 UI 保持响应.您可以使用 NSURLConnectionDelegate 回调来做到这一点.NSURLConnection 有一个小缺点:你的代码必须是解耦的.您希望在委托函数中可用的任何变量都需要保存到 ivars 或您请求的 userInfo 字典中.
Aim to make all your url connections asynchronous so your UI remains responsive. You can do this with NSURLConnectionDelegate callbacks. NSURLConnection has a small drawback: your code must be decoupled. Any variables you want available in the delegate functions will need to be saved to ivars or in your request's userInfo dict.
或者,您可以使用 GCD,当与 __block 限定符结合使用时,允许您在声明时指定错误/返回代码 - 对于一次性提取很有用.
Alternatively you can use GCD, which, when coupled with the __block qualifiers, allows you to specify error/return code at the point you declare it - useful for one off fetches.
事不宜迟,这是一个快速而肮脏的 url 编码器:
Without further ado, here's a quick and dirty url-encoder:
- (NSData*)encodeDictionary:(NSDictionary*)dictionary {
NSMutableArray *parts = [[NSMutableArray alloc] init];
for (NSString *key in dictionary) {
NSString *encodedValue = [[dictionary objectForKey:key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *encodedKey = [key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *part = [NSString stringWithFormat: @"%@=%@", encodedKey, encodedValue];
[parts addObject:part];
}
NSString *encodedDictionary = [parts componentsJoinedByString:@"&"];
return [encodedDictionary dataUsingEncoding:NSUTF8StringEncoding];
}
使用像 JSONKit 这样的 JSON 库使编码变得更容易,考虑一下!
Using a JSON library like JSONKit makes encoding things easier, consider it!
// .h
@interface ViewController : UIViewController<NSURLConnectionDelegate>
@end
// .m
@interface ViewController () {
NSMutableData *receivedData_;
}
@end
...
- (IBAction)asyncButtonPushed:(id)sender {
NSURL *url = [NSURL URLWithString:@"http://localhost/"];
NSDictionary *postDict = [NSDictionary dictionaryWithObjectsAndKeys:@"user", @"username",
@"password", @"password", nil];
NSData *postData = [self encodeDictionary:postDict];
// Create the request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
[request setValue:[NSString stringWithFormat:@"%d", postData.length] forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request
delegate:self];
[connection start];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[receivedData_ setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receivedData_ appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSLog(@"Succeeded! Received %d bytes of data", [receivedData_ length]);
NSString *responeString = [[NSString alloc] initWithData:receivedData_
encoding:NSUTF8StringEncoding];
// Assume lowercase
if ([responeString isEqualToString:@"true"]) {
// Deal with true
return;
}
// Deal with an error
}
方法 2 - Grand Central Dispatch 异步函数:
// .m
- (IBAction)dispatchButtonPushed:(id)sender {
NSURL *url = [NSURL URLWithString:@"http://www.apple.com/"];
NSDictionary *postDict = [NSDictionary dictionaryWithObjectsAndKeys:@"user", @"username",
@"password", @"password", nil];
NSData *postData = [self encodeDictionary:postDict];
// Create the request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
[request setValue:[NSString stringWithFormat:@"%d", postData.length] forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Peform the request
NSURLResponse *response;
NSError *error = nil;
NSData *receivedData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
if (error) {
// Deal with your error
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
NSLog(@"HTTP Error: %d %@", httpResponse.statusCode, error);
return;
}
NSLog(@"Error %@", error);
return;
}
NSString *responeString = [[NSString alloc] initWithData:receivedData
encoding:NSUTF8StringEncoding];
// Assume lowercase
if ([responeString isEqualToString:@"true"]) {
// Deal with true
return;
}
// Deal with an error
// When dealing with UI updates, they must be run on the main queue, ie:
// dispatch_async(dispatch_get_main_queue(), ^(void){
//
// });
});
}
方法 3 - 使用 NSURLConnection 便利函数
+ (void)sendAsynchronousRequest:(NSURLRequest *)request queue:(NSOperationQueue *)queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler
希望这会有所帮助.
这篇关于NSURLRequest : 发布数据并读取发布的页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!