如何从网络上面请求数据
首先明白网络请求的原理和过程
/*
ISO(国际标准化组织)指定了 OSI 网络参考模型:
1.应用层;
2.表示层;
3.会话层;
4.传输层;
5.网络层;
6.数据链路层;
7.屋里层;
没多久就被美国国防部换掉 指定新的协议
1.应用层:HTTP 协议 FTP SMTP(邮件遵守协议)
2.传输层:TCP (安全的 需要两方连通性) UDP (不安全 ,单方面操作)
3.网络层:IP
4.物理层:WiFi 以太网;
HTTP 协议 是一种超文本协议,基于请求和响应协议,通过请求和响应才能建立连接;这种连接是一种短链接
如何建立连接:
第一步:三次握手
1.客户端发送请求;
2.服务器收到请求,并通知客户端;
3.客户端收到服务器的确定信息;
如何断开连接:(四次握手)
1.客户端发送断开连接的请求;
2.服务器收到请求,并告知客户端可以断开连接;
3.服务器发送断开连接的请求给客户端;
4.客户端收到请求,并告知服务器此时可以断开;
请求的主流方式:
1.GET 请求:网址和参数融合在一起
2.POST 请求;
*/
一 GET 方法请求
用 storyBoard 来建立
//同步请求,由主线程完成网络请求的任务,在请求的任务没有完成之前,用户的所有交互事件都无法处理 会造成卡顿,影响用户体验;
图上的同步是一个 BarButton 的点击事件
- (IBAction)requestSynAction:(UIBarButtonItem *)sender{
// 1.获取网址URL 转化为字符串
NSString *urlStr =[NSString stringWithFormat:@"http://api.map.baidu.com/place/v2/search?query=%@®ion=%@&output=json&ak=6E823f587c95f0148c19993539b99295",@"大保健",@"郑州"];
//2.地址中不可以出现汉字 如果出现 则需要 url 转码
NSString *changeURL =[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
// 3.创建网址对象
NSURL *url =[[NSURL alloc]initWithString:changeURL];
// 4.创建网络请求对象 NSURLrequest 默认的请求方式 就是 getter 请求;
NSURLRequest *request =[NSURLRequest requestWithURL:url];
// 5.创建网络连接
// 5.1创建一个响应对象
NSURLResponse *response =nil;//用来存储服务器响应信息
NSError *error =nil;//用来存储请求失败的信息
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
//写到这里 就是第一部分的完成 下一个部分就是解析网址上面的数据 为了方便 我们将它封装为一个方法
[self parsetData:data];
}
-(void)parsetData:(NSData *)data{
self.dataSource =nil ;
// 解析 拿到网络请求的数据后,就可以进行了 这个是 JSON 解析
NSMutableDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingMutableContainers) error:nil];
//
NSArray *businssArr = dic[@"results"];
// 遍历字典
for (NSDictionary *d in businssArr) {
//最近的遍历我们都是用到了 MODEL 类 这是一个非常方便的方法 推荐大家多使用
BusinessMode *business =[[BusinessMode alloc]init];
[business setValuesForKeysWithDictionary:d];
[self.dataSource addObject:business];
[business release];
}
//刷新 重新走程序
[self.tableView reloadData];
}
想让 cell 上面显示我们请求下的数据 cell 的重用不能忘记
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
#warning Potentially incomplete method implementation.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
#warning Incomplete method implementation.
return self.dataSource.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
BusinessCell *cell = [tableView dequeueReusableCellWithIdentifier:@"businessCell" forIndexPath:indexPath];
BusinessMode *business =self.dataSource[indexPath.row];
// Configure the cell...
cell.businessM = business;
return cell;
}
//异步请求,系统默认开辟子线程,由子线程完成请求任务,主线程还做自己的事情 提高用户体验 (开辟空间会造成内存消耗 但是节省时间);
pragma mark—–BarButtonItem 点击事件——
//两种: block 解析; delegate
- (IBAction)requestAsynAction:(UIBarButtonItem *)sender {
self.dataSource =nil;
// 1.获取地址
NSString *urlStr =[NSString stringWithFormat:@"http://api.map.baidu.com/place/v2/search?query=%@®ion=%@&output=json&ak=6E823f587c95f0148c19993539b99295",@"大保健",@"郑州"];
// 2.有汉字 转化为字符串
NSString *changeUrl =[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
// 3.创建网址对象
NSURL *url =[[NSURL alloc]initWithString:changeUrl];
//4.创建请求对象 ,并指定请求方式
NSURLRequest *request =[NSURLRequest requestWithURL:url];
// 5.与服务器建立连接
// 5.1block
//block 里面 是不能使用 self 的 所以我们转换一下
__block GetTableViewController *weakSelf =self;
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
[weakSelf parsetData:data];
}];
[self.tableView reloadData];
// 5.2 代理网络请求 delegate 顾名思义 我们需要遵守她的协议 他之前的步骤和 block 一样 所以 上面的就不再重复
[NSURLConnection connectionWithRequest:request delegate:self];
}
//代理方法是写在外面的
#pragma mark----实现异步 delegate 解析方法-------
//当接收到服务器响应的时候触发
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
}
//当服务器传输数据的时候触发 不止一次会触发 她会触发很多次
//(1.网络情况,
// 2.数据大小; 当请求的数据比较大的时候 ,服务器不会将所有的数据一次性传送 部分的传送; 每传送一次 就会触发这个方法,为了保证能拿到完整数据, 这个时候要对数据进行拼接)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
// 1.拿到数据之前 将用来拼接的拼接数据对象初始化
self.data =[NSMutableData data];
// 2.拼接方法
[self.data appendData:data];
}
//当服务器传输数据结束的时候触发
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
//在传输数据完之后 完成拼接方法
[self parsetData:self.data];
NSLog(@"%@",self.data);
}
//自代理协议方法 传输失败的时候触发
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
}
二 POST 方法
POST 的地址和 GET 的 略有不同分两部分 :一个是地址,一个是参数 所以我们需要建立两个对象 来保存
1.同步事件
http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx/?date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213
//同步
- (IBAction)postSynRequest:(UIBarButtonItem *)sender {
self.dataSource =nil;
//http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx/?date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213
//date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213
// 1.将网址存为字符串对象
NSString *urlStr =[NSString stringWithFormat:@"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx/"];
// 2.初始化网址对象
NSURL *url =[[NSURL alloc]initWithString:urlStr];
// 3.创建网络响应对象
NSMutableURLRequest *urlRequest =[[NSMutableURLRequest alloc]initWithURL:url];
// 4.设置请求方式 GET 的方式没有设置 是因为他是默认的
urlRequest .HTTPMethod = @"POST";
// 5.创建字符串对象,用来保存 post 请求中的参数
NSString *argStr =[NSString stringWithFormat:@"date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213"];
//将参数字符串转化为 NSData对象 赋值给 HTTPBody
urlRequest.HTTPBody = [argStr dataUsingEncoding:NSUTF8StringEncoding];
// 6建立服务器连接
NSURLResponse *response = nil;//保存服务器响应信息
NSError *error =nil;//用来存储请求失败的信息
NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:& response error:&error];
//之前封装好的方法
[self parsetData:data];
}
2.异步事件
//异步
- (IBAction)postAsynRequest:(UIBarButtonItem *)sender {
//获取地址转化为字符串对象
NSString *urlStr =[NSString stringWithFormat:@"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx/"];
//2.创建网址对象并初始化
NSURL *url =[[NSURL alloc]initWithString:urlStr];
// 3.创建请求 响应对象 并初始化对象
NSMutableURLRequest *mutRequest =[[NSMutableURLRequest alloc]initWithURL:url];
// 4.设置请求方式
mutRequest .HTTPMethod = @"POST";
// 5.创建能保存参数的字符串对象
NSString *argStr =[NSString stringWithFormat:@"date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213"];
//将参数字符串转化为 NSData 赋值给 HTTPBody
mutRequest.HTTPBody =[argStr dataUsingEncoding:NSUTF8StringEncoding];
// 6.建立服务器连接
__block PostTableViewController *weakSelf= self;
[NSURLConnection sendAsynchronousRequest:mutRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
[weakSelf parsetData:data];
}];
}
三 请求图片
#pragma mark----点击事件-----
- (IBAction)buttonSynRequest:(UIButton *)sender {
//1.获取URL 转化成字符串
NSString *urlStr =[NSString stringWithFormat:@"http://image.zcool.com.cn/56/13/1308200901454.jpg"];
// 2.创建网址对象
NSURL *url =[[NSURL alloc]initWithString:urlStr];
// 3.创建网络请求对象
NSURLRequest *request =[NSURLRequest requestWithURL:url];
// 4.创建网络连接
NSURLResponse *response =nil;//存储服务器响应信息
NSError *error = nil;//存储请求失败信息
NSData *data =[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
// 5.用网络请求的数据 给 image赋值图片
// 不需要解析的数据:视频;音乐;图片
UIImage *image =[UIImage imageWithData:data];
self.BigImage.image = image;
}
总结:
1.不论是 GET POST 前几步 几乎都是相同的步骤
①获取地址转化为字符串对象
②转化为字符串(有汉字的状态下)
③创建网址对象并初始化
④创建请求 响应对象 并初始化对象
⑤设置请求方式(POST 方法下)
⑥建立服务器连接;
⑦解析数据(视频,图片 ,音乐除外)
2.解析的方法就是剥数据的过程 参考 plist 取数据 封装成方法可以让你在多种请求方法下快速解析