网络编程(GET, POST)
客户端展示网络数据的过程:
1.客户端发送请求给服务器端
2.服务器端收到请求,把数据(XML, JSON)传给客户端
3.客户端要对数据进行解析, 提取有用数据
4.然后在控件(label, tableView, imageView等等)上进行展示
客户端与服务器端进行沟通, 需要一定的规则(所谓的协议), 常用的协议:HTTP, 超文本传输协议
HTTP请求的方式
1.GET
2.POST
区别: 数据存放的位置不一样
GET请求数据存放在网址(URL)的后面, ?前是URL, ?后是参数, 参数以key=value的形式出现, 多个键值对用&连接
POST请求数据存放在请求体(HTTPBody)中
注:请求的格式可以看接口文档(API文档)
发出请求的方式:
1.同步请求, 发出请求后,必须等待服务器的回应, 才能继续执行
2.异步请求, 发出请求后, 无需等待服务器回应, 可以继续执行
同步GET请求
- (IBAction)get1:(id)sender { NSURL, 网址类 NSURL *url = [NSURL URLWithString:@"http://api.hudong.com/iphonexml.do?type=focus-c"]; NSURLRequest, 请求类, 继承于NSObject NSURLRequest *request = [NSURLRequest requestWithURL:url]; NSURLConnection, 网络连接类, 继承于NSObject, 用于发出请求 //发出同步请求 NSURLResponse *response = nil; NSError *error = nil; NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; NSLog(@"response: %@ error: %@", response, error); NSLog(@"%@", data); 将data转成NSString NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"%@", string); XML解析 // NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data]; }
同步POST请求
- (IBAction)post1:(id)sender { post请求的url后面没有参数 NSURL *url = [NSURL URLWithString:@"http://api.hudong.com/iphonexml.do"]; post请求的参数需要放在HTTPBody中, NSURLRequest不允许修改HTTPBody, 需要使用NSMutableURLRequest, 才能修改HTTPBody NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 请求体 NSString *value = @"type=focus-c"; request.HTTPBody = [value dataUsingEncoding:NSUTF8StringEncoding]; 请求方式, 默认为@"GET" request.HTTPMethod = @"POST"; NSURLResponse *response = nil; NSError *error = nil; NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"%@", string); [string release]; }
异步GET请求
- (IBAction)get2:(id)sender { //1 NSString *string = @"http://image.zcool.com.cn/56/13/1308200901454.jpg"; URL中不能出现中文, 如果出现, 需要对字符串中的中文进行转码 NSString *rightString = [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSLog(@"%@", rightString); NSURL *url = [NSURL URLWithString: rightString]; //2 NSURLRequest *request = [NSURLRequest requestWithURL:url]; //3 异步请求需要创建connection, 并指定delegate, 当数据返回时, 会调用代理方法 NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; //开始连接 [connection start]; //释放 [connection release]; }
delegate方法
#pragma mark - NSURLConnectionDelegate - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { NSLog(@"出现错误:%@", error); } - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { NSLog(@"收到服务器的回应: %@", response); self.mData = [NSMutableData dataWithCapacity:0]; } 服务器传数据给客户端, 会把数据拆分成多个数据包, 这个方法会执行多次, 每次收到一个数据包就执行一次, 并且应该把数据包都拼接在一起, 形成完整的数据 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { NSLog(@"已经收到数据: %@", data); [self.mData appendData:data]; } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { NSLog(@"网络请求已经结束"); self.imageView.image = [UIImage imageWithData:self.mData]; }
异步POST请求
- (IBAction)post2:(id)sender { //1 NSURL *url = [NSURL URLWithString:@"http://api.tudou.com/v3/gw"]; //2 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; NSString *valule = @"method=album.channel.get&appKey=myKey&format=json&channel=t&pageNo=1&pageSize=10"; request.HTTPBody = [valule dataUsingEncoding:NSUTF8StringEncoding]; request.HTTPMethod = @"POST"; //3 发出异步请求 //3.1 // NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; // [connection start]; // [connection release]; //3.2 [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 当请求结束才会执行block, 此时的data是一个完整的数据 NSLog(@"%@", response); NSLog(@"%@", connectionError); NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"%@", string); }]; }
点击imageView出现图片
- (IBAction)tap:(id)sender { //1 NSURL *url = [NSURL URLWithString:@"http://image.zcool.com.cn/56/13/1308200901454.jpg"]; //2 NSURLRequest *requst = [NSURLRequest requestWithURL:url]; //3 NSData *data = [NSURLConnection sendSynchronousRequest:requst returningResponse:nil error:nil]; NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"%@", string); //4. NSData转UIImage UIImage *image = [UIImage imageWithData:data]; //5,在UIImageView上展示图片 self.imageView.image = image; }
同步请求的缺点: 当数据比较大时, 由于需要等待服务器端把所有数据传过来, 如果网速比较慢, 就会造成应用程序"假死"状态(不能做其他操作, 必须等待数据全部传过来)实现代码:
#import "NewsTableViewController.h" #import "XHNews.h" @interface NewsTableViewController () - (IBAction)refresh:(id)sender; @property (nonatomic, retain) NSMutableArray *dataArray; @end @implementation NewsTableViewController - (void)dealloc { [_dataArray release]; [super dealloc]; } - (void)viewDidLoad { [super viewDidLoad]; // Uncomment the following line to preserve selection between presentations. // self.clearsSelectionOnViewWillAppear = NO; // Uncomment the following line to display an Edit button in the navigation bar for this view controller. // self.navigationItem.rightBarButtonItem = self.editButtonItem; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { // Return the number of sections. return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // Return the number of rows in the section. return self.dataArray.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *identifier = @"identifier1"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleSubtitle) reuseIdentifier:identifier] autorelease]; } XHNews *news = [[XHNews alloc] init]; news = self.dataArray[indexPath.row]; cell.textLabel.text = news.title; cell.detailTextLabel.text = news.desc; NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:news.hot_pic]]; cell.imageView.image = [UIImage imageWithData:data]; return cell; } - (IBAction)refresh:(id)sender { //异步GET请求 NSURL *url = [NSURL URLWithString:@"http://www.bjnews.com.cn/api/get_hotlist.php?page=1"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { NSLog(@"%@", response); NSLog(@"%@", connectionError); //JSON解析 NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil]; NSLog(@"%@", dic); //数据封装 self.dataArray = [NSMutableArray arrayWithCapacity:20]; for (NSDictionary *dictionary in dic[@"list"]) { XHNews *news = [[XHNews alloc] init]; [news setValuesForKeysWithDictionary:dictionary]; [self.dataArray addObject:news]; [news release]; } NSLog(@"%@", self.dataArray); //展示数据(刷新tableView) [self.tableView reloadData]; }]; } @end
时间: 2024-10-21 07:27:57