网络请求
/*
一 客户端发起请求的时候 要知道的几点
1. 向谁请求
2. 请求什么
3. 发送请求
二 具体操作
1. 建立请求 (1. 向谁请求 , 2. 请求什么 )
2. 发送请求
3. 接收数据
*/
//同步 get 与 异步 get 方式
#import "FirstViewController.h"
@interface FirstViewController ()
@property ( nonatomic , retain ) NSMutableData *receivedData; // 用于保存服务器传送过来的数据
@end
@implementation FirstViewController
- ( void )viewDidLoad
{
[ super viewDidLoad ];
// Do any additional setup after loading the view, typically from a nib.
}
- ( void )didReceiveMemoryWarning
{
[ super didReceiveMemoryWarning ];
// Dispose of any resources that can be recreated.
}
// 同步 与 异步 指的是连接的过程是 同步或者是异步
// 同步 与 异步 只有连接的过程不一样
// 同步 GET 请求
- ( IBAction )synGET:( UIButton *)sender
{
// 创建一个请求 ----NSURLRequest
//1. 创建一个 URL 对象 ( 向谁请求 ) (GET 方式 URL 中包含了请求地址和请求内容 )
NSURL *url = [[ NSURL alloc ] initWithString : @"http://www.36kr.com/api/v1/topics/category/digest.json?token=e1cbdfe589bff295bb29%3A12375&page=2&per_page=15" ];
NSURLRequest *request = [[ NSURLRequest alloc ] initWithURL :url cachePolicy : NSURLRequestUseProtocolCachePolicy timeoutInterval :10];
// 发送一个同步请求
NSURLResponse *response = nil ;
// 这个 data 就是要接收的所有数据
NSData *data = [ NSURLConnection sendSynchronousRequest :request returningResponse :&response error : nil ];
// 通过 json 处理数据
NSArray *array = [ NSJSONSerialization JSONObjectWithData :data options : NSJSONReadingMutableContainers error : nil ];
for ( int i=0; i<[array count ]; i++) {
for ( NSString *key in [array objectAtIndex :i]) {
NSLog ( @"%@ %@" ,key,[[array objectAtIndex :i] objectForKey :key]);
}
}
}
// 异步 GET 请求
- ( IBAction )asynGET:( UIButton *)sender {
// 创建一个请求 ----NSURLRequest
//1. 创建一个 URL 对象 ( 向谁请求 ) (GET 方式 URL 中包含了请求地址和请求内容 )
NSURL *url = [[ NSURL alloc ] initWithString : @"http://www.36kr.com/api/v1/topics/category/digest.json?token=e1cbdfe589bff295bb29%3A12375&page=2&per_page=15" ];
NSURLRequest *request = [[ NSURLRequest alloc ] initWithURL :url cachePolicy : NSURLRequestUseProtocolCachePolicy timeoutInterval :10];
// 创建一个连接 把 request 发送过去 , 另外通过这个连接 接收服务器给的数据 . -----NSURLConnection
NSURLConnection *connect = [[ NSURLConnection alloc ] initWithRequest :request delegate : self ];
[connect release ];
}
#pragma mark -- NSURLConnectionDataDelegate 它继承了协议 NSURLConnectionDelegate
// 接收到服务器的回应
- ( void )connection:( NSURLConnection *)connection didReceiveResponse:( NSURLResponse *)response
{
NSLog ( @" 接收到来自服务器的回应 " );
// 接收到回应的时候 创建一个可变的 data ( 目前 0 字节 )
self . receivedData = [ NSMutableData data ];
}
// 接收到服务器 传送过来的 数据 这个方法可能会执行多次 , ( 服务器发的数据较大的时候 , 会分多次发送 , 我们会接受多次 )
- ( void )connection:( NSURLConnection *)connection didReceiveData:( NSData *)data
{
NSLog ( @" 接收到来自服务器传送的数据 " );
// 拼接服务器发送过来的数据
[ self . receivedData appendData :data];
}
// 数据接收完毕 或者 数据上传完毕 会调用这个方法
- ( void )connectionDidFinishLoading:( NSURLConnection *)connection
{
NSLog ( @" 数据接收完毕 数据上传完毕 " );
//NSString *string = [[NSString alloc]initWithData:self.receivedData encoding:NSUTF8StringEncoding];
//json 处理数据
NSMutableArray *array = [ NSJSONSerialization JSONObjectWithData : self . receivedData options : NSJSONReadingMutableContainers error : nil ];
NSLog ( @"%@" ,array);
}
#pragma mark -- NSURLConnectionDelegate
// 请求超时 URL 错误 或者是断网等情况 会调用这个方法
- ( void )connection:( NSURLConnection *)connection didFailWithError:( NSError *)error
{
NSLog ( @" 请求错误 " );
}
@end
1.http 协议的概念 超文本传输协议 用于从万维网服务器传送超文本到本地浏览器的传输协议 标准的c/s
2.客户端请求 服务器处理请求
3.请求方式 get 与 post (常用的两种方式)
GET 请求方式:
url?参数= 值&参数= 值... 这种把参数直接拼接到 URL 之后的方式的数据请求是 get 方式的数据请求
优点:1.可以作为网址直接搜索数据 2.便于修改
缺点:1.有长度限制 拼接 URL 之后的长度不能大于255B 如果大于255B 则舍去255B之后的东西 . 如果提交数据的长度大于255B (一张图片)就不会使用这种方式 会使数据请求不完整 ,出现错误 2 不安全 参数暴露,对于安全性有要求的(如用户名登录) 不会使用这种方式 获取数据的时候 常用 get 而提交数据的时候常用 post
POST 请求方式
将URL 和 请求的参数分开了 URL+请求体 请求体(参数 转化为 NSData 数据流 没有长度限制 ,并且比较安全)
同步 请求 与异步请求 区别
1.同步 与 异步 指的是连接的过程是 同步或者是异步
2.同步就是当在请求服务器数据的时候,没有请求到的时候 用户只能等待 当点击其他按钮或做其他操作的时候这些操作的响应会被放到 响应队列中 只有当当前请求结束 才响应其他的操作
3.异步 当在请求服务器数据的时候,没有请求到的时候 用户可以同时做其他操作 因为异步请求方式 在创建连接的时候,会指定代理,连接之后的处理 都是通过代理来完成的
异步请求
一 客户端发起请求的时候 要知道的几点
1.向谁请求
2.请求什么
3.发送请求
二 具体操作
1.建立请求 (1.向谁请求, 2.请求什么)
2.发送请求
3.接收数据
#import
<UIKit/UIKit.h>
@interface FirstViewController : UIViewController < NSURLConnectionDataDelegate ]]>
@end
@interface FirstViewController : UIViewController < NSURLConnectionDataDelegate ]]>
@end
/*
一 客户端发起请求的时候 要知道的几点
1. 向谁请求
2. 请求什么
3. 发送请求
二 具体操作
1. 建立请求 (1. 向谁请求 , 2. 请求什么 )
2. 发送请求
3. 接收数据
*/
//同步 get 与 异步 get 方式
#import "FirstViewController.h"
@interface FirstViewController ()
@property ( nonatomic , retain ) NSMutableData *receivedData; // 用于保存服务器传送过来的数据
@end
@implementation FirstViewController
- ( void )viewDidLoad
{
[ super viewDidLoad ];
// Do any additional setup after loading the view, typically from a nib.
}
- ( void )didReceiveMemoryWarning
{
[ super didReceiveMemoryWarning ];
// Dispose of any resources that can be recreated.
}
// 同步 与 异步 指的是连接的过程是 同步或者是异步
// 同步 与 异步 只有连接的过程不一样
// 同步 GET 请求
- ( IBAction )synGET:( UIButton *)sender
{
// 创建一个请求 ----NSURLRequest
//1. 创建一个 URL 对象 ( 向谁请求 ) (GET 方式 URL 中包含了请求地址和请求内容 )
NSURL *url = [[ NSURL alloc ] initWithString : @"http://www.36kr.com/api/v1/topics/category/digest.json?token=e1cbdfe589bff295bb29%3A12375&page=2&per_page=15" ];
NSURLRequest *request = [[ NSURLRequest alloc ] initWithURL :url cachePolicy : NSURLRequestUseProtocolCachePolicy timeoutInterval :10];
// 发送一个同步请求
NSURLResponse *response = nil ;
// 这个 data 就是要接收的所有数据
NSData *data = [ NSURLConnection sendSynchronousRequest :request returningResponse :&response error : nil ];
// 通过 json 处理数据
NSArray *array = [ NSJSONSerialization JSONObjectWithData :data options : NSJSONReadingMutableContainers error : nil ];
for ( int i=0; i<[array count ]; i++) {
for ( NSString *key in [array objectAtIndex :i]) {
NSLog ( @"%@ %@" ,key,[[array objectAtIndex :i] objectForKey :key]);
}
}
}
// 异步 GET 请求
- ( IBAction )asynGET:( UIButton *)sender {
// 创建一个请求 ----NSURLRequest
//1. 创建一个 URL 对象 ( 向谁请求 ) (GET 方式 URL 中包含了请求地址和请求内容 )
NSURL *url = [[ NSURL alloc ] initWithString : @"http://www.36kr.com/api/v1/topics/category/digest.json?token=e1cbdfe589bff295bb29%3A12375&page=2&per_page=15" ];
NSURLRequest *request = [[ NSURLRequest alloc ] initWithURL :url cachePolicy : NSURLRequestUseProtocolCachePolicy timeoutInterval :10];
// 创建一个连接 把 request 发送过去 , 另外通过这个连接 接收服务器给的数据 . -----NSURLConnection
NSURLConnection *connect = [[ NSURLConnection alloc ] initWithRequest :request delegate : self ];
[connect release ];
}
#pragma mark -- NSURLConnectionDataDelegate 它继承了协议 NSURLConnectionDelegate
// 接收到服务器的回应
- ( void )connection:( NSURLConnection *)connection didReceiveResponse:( NSURLResponse *)response
{
NSLog ( @" 接收到来自服务器的回应 " );
// 接收到回应的时候 创建一个可变的 data ( 目前 0 字节 )
self . receivedData = [ NSMutableData data ];
}
// 接收到服务器 传送过来的 数据 这个方法可能会执行多次 , ( 服务器发的数据较大的时候 , 会分多次发送 , 我们会接受多次 )
- ( void )connection:( NSURLConnection *)connection didReceiveData:( NSData *)data
{
NSLog ( @" 接收到来自服务器传送的数据 " );
// 拼接服务器发送过来的数据
[ self . receivedData appendData :data];
}
// 数据接收完毕 或者 数据上传完毕 会调用这个方法
- ( void )connectionDidFinishLoading:( NSURLConnection *)connection
{
NSLog ( @" 数据接收完毕 数据上传完毕 " );
//NSString *string = [[NSString alloc]initWithData:self.receivedData encoding:NSUTF8StringEncoding];
//json 处理数据
NSMutableArray *array = [ NSJSONSerialization JSONObjectWithData : self . receivedData options : NSJSONReadingMutableContainers error : nil ];
NSLog ( @"%@" ,array);
}
#pragma mark -- NSURLConnectionDelegate
// 请求超时 URL 错误 或者是断网等情况 会调用这个方法
- ( void )connection:( NSURLConnection *)connection didFailWithError:( NSError *)error
{
NSLog ( @" 请求错误 " );
}
@end
//异步请求
#import
<UIKit/UIKit.h>
@interface SecondViewController : UIViewController < NSURLConnectionDataDelegate ]]>
@end
@interface SecondViewController : UIViewController < NSURLConnectionDataDelegate ]]>
@end
#import
"SecondViewController.h"
#import "NewsInfo.h"
@interface SecondViewController ()
{
long long _contentLength; // 内容长度
IBOutlet UIProgressView *_progressView;
}
@property ( nonatomic , retain ) NSMutableData *receiverData;
@property ( nonatomic , retain ) NSMutableArray *newsMutableArray;
@end
@implementation SecondViewController
- ( void )viewDidLoad
{
[ super viewDidLoad ];
// Do any additional setup after loading the view, typically from a nib.
self . newsMutableArray = [ NSMutableArray arrayWithCapacity :5];
}
- ( void )didReceiveMemoryWarning
{
[ super didReceiveMemoryWarning ];
// Dispose of any resources that can be recreated.
}
- ( IBAction )synPOST:( UIButton *)sender
{
// 建立一个异步的 post 请求
NSURL *url = [ NSURL URLWithString : @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx" ];
//NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];
//url+ 请求体
NSMutableURLRequest *request = [[ NSMutableURLRequest alloc ] initWithURL :url cachePolicy : NSURLRequestUseProtocolCachePolicy timeoutInterval :10];
// 设置 请求体
NSString *str2 = @"date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213" ;
// 字符串与 NSData 之间的互转
// 将 NSString 类型的一个对象转化为 NSData 对象
NSData *data = [str2 dataUsingEncoding : NSUTF8StringEncoding ];
// 将 NSData 对象转化为 NSString 对象
//NSString *str4 = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
[request setHTTPBody : data];
// 默认的请求方式是 GET 方式 , 要改为 POST 方式
[request setHTTPMethod : @"POST" ]; // 注意 要大写
// 发送一个同步请求
NSURLResponse *response = nil ;
NSData *receiver1Data = [ NSURLConnection sendSynchronousRequest :request returningResponse :&response error : nil ];
// 解析数据
NSDictionary *dic = [ NSJSONSerialization JSONObjectWithData :receiver1Data options : NSJSONReadingMutableContainers error : nil ];
NSLog ( @"%@" ,dic);
}
- ( IBAction )asynPOST:( UIButton *)sender
{
NSString *str = @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx?date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213" ;
//NSString *str1 = [[str componentsSeparatedByString:@"?"] objectAtIndex:0];
// 建立一个异步的 post 请求
NSURL *url = [ NSURL URLWithString : @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx" ];
//NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];
//url+ 请求体
NSMutableURLRequest *request = [[ NSMutableURLRequest alloc ] initWithURL :url cachePolicy : NSURLRequestUseProtocolCachePolicy timeoutInterval :10];
// 设置 请求体
NSString *str2 = @"date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213" ;
// 字符串与 NSData 之间的互转
// 将 NSString 类型的一个对象转化为 NSData 对象
NSData *data = [str2 dataUsingEncoding : NSUTF8StringEncoding ];
// 将 NSData 对象转化为 NSString 对象
//NSString *str4 = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
[request setHTTPBody : data];
// 默认的请求方式是 GET 方式 , 要改为 POST 方式
[request setHTTPMethod : @"POST" ]; // 注意 要大写
// 建立连接 方法 1:
// [[[NSURLConnection alloc]initWithRequest:request delegate:self]autorelease];
// 建立连接 方法 2:
// 使用这个方法 不用指定代理 但是可以创建线程
// 创建一个
NSOperationQueue *queue = [[ NSOperationQueue alloc ] init ];
[ NSURLConnection sendAsynchronousRequest :request queue :queue completionHandler :^( NSURLResponse *response, NSData *data, NSError *connectionError) {
// 这里要指定 在数据请求结束之后要做的事情 data 是请求的完整数据 connectionError 是网络连接的错误
// 即在 connectionDidFinishLoading 中做的事情
// 这个参数是个 block 相当于苹果对于异步请求的一个封装 但是用这种方法无法显示进度
// 所以如果要显示进度 就要自己使用 方法 1 去执行代理方法
NSMutableDictionary *dic = [ NSJSONSerialization JSONObjectWithData :data options : NSJSONReadingMutableContainers error : nil ];
NSLog ( @"%@" ,dic);
}];
}
- ( void )connection:( NSURLConnection *)connection didReceiveResponse:( NSURLResponse *)response
{
self . receiverData = [ NSMutableData data ];
/*
// 获取 response 信息
NSLog(@"%@",response);
// 有的 response 中没有 contentlength 这个字段 这时候就无法获取内容长度大小
// 获取请求的的数据的长度
_contentLength = [response expectedContentLength];
*/
}
- ( void )connection:( NSURLConnection *)connection didReceiveData:( NSData *)data
{
[ self . receiverData appendData :data];
/*
// 求当前已经获取的数据的大小
NSUInteger currentLenth = [self.receiverData length];
// 求进度比例
float progress = 1.0*currentLenth / _contentLength;
// 可以设置进度条的进度
//UIProgressView *progressView = [[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleDefault];
//progressView.progress = progress;
//_progressView.progress = progress;
*/
}
- ( void )connectionDidFinishLoading:( NSURLConnection *)connection
{
NSDictionary *dic = [ NSJSONSerialization JSONObjectWithData : self . receiverData options : NSJSONReadingMutableContainers error : nil ];
NSArray *newsArray = [dic objectForKey : @"news" ];
for ( NSDictionary *newDic in newsArray) {
NewsInfo *newsInfo = [[ NewsInfo alloc ] init ];
[newsInfo setValuesForKeysWithDictionary :newDic];
[ self . newsMutableArray addObject :newsInfo];
[newsInfo release ];
}
NSLog ( @"%@" , self . newsMutableArray );
}
- ( void )connection:( NSURLConnection *)connection didFailWithError:( NSError *)error
{
}
- ( void )dealloc {
[ _progressView release ];
[ super dealloc ];
}
@end
#import "NewsInfo.h"
@interface SecondViewController ()
{
long long _contentLength; // 内容长度
IBOutlet UIProgressView *_progressView;
}
@property ( nonatomic , retain ) NSMutableData *receiverData;
@property ( nonatomic , retain ) NSMutableArray *newsMutableArray;
@end
@implementation SecondViewController
- ( void )viewDidLoad
{
[ super viewDidLoad ];
// Do any additional setup after loading the view, typically from a nib.
self . newsMutableArray = [ NSMutableArray arrayWithCapacity :5];
}
- ( void )didReceiveMemoryWarning
{
[ super didReceiveMemoryWarning ];
// Dispose of any resources that can be recreated.
}
- ( IBAction )synPOST:( UIButton *)sender
{
// 建立一个异步的 post 请求
NSURL *url = [ NSURL URLWithString : @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx" ];
//NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];
//url+ 请求体
NSMutableURLRequest *request = [[ NSMutableURLRequest alloc ] initWithURL :url cachePolicy : NSURLRequestUseProtocolCachePolicy timeoutInterval :10];
// 设置 请求体
NSString *str2 = @"date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213" ;
// 字符串与 NSData 之间的互转
// 将 NSString 类型的一个对象转化为 NSData 对象
NSData *data = [str2 dataUsingEncoding : NSUTF8StringEncoding ];
// 将 NSData 对象转化为 NSString 对象
//NSString *str4 = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
[request setHTTPBody : data];
// 默认的请求方式是 GET 方式 , 要改为 POST 方式
[request setHTTPMethod : @"POST" ]; // 注意 要大写
// 发送一个同步请求
NSURLResponse *response = nil ;
NSData *receiver1Data = [ NSURLConnection sendSynchronousRequest :request returningResponse :&response error : nil ];
// 解析数据
NSDictionary *dic = [ NSJSONSerialization JSONObjectWithData :receiver1Data options : NSJSONReadingMutableContainers error : nil ];
NSLog ( @"%@" ,dic);
}
- ( IBAction )asynPOST:( UIButton *)sender
{
NSString *str = @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx?date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213" ;
//NSString *str1 = [[str componentsSeparatedByString:@"?"] objectAtIndex:0];
// 建立一个异步的 post 请求
NSURL *url = [ NSURL URLWithString : @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx" ];
//NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];
//url+ 请求体
NSMutableURLRequest *request = [[ NSMutableURLRequest alloc ] initWithURL :url cachePolicy : NSURLRequestUseProtocolCachePolicy timeoutInterval :10];
// 设置 请求体
NSString *str2 = @"date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213" ;
// 字符串与 NSData 之间的互转
// 将 NSString 类型的一个对象转化为 NSData 对象
NSData *data = [str2 dataUsingEncoding : NSUTF8StringEncoding ];
// 将 NSData 对象转化为 NSString 对象
//NSString *str4 = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
[request setHTTPBody : data];
// 默认的请求方式是 GET 方式 , 要改为 POST 方式
[request setHTTPMethod : @"POST" ]; // 注意 要大写
// 建立连接 方法 1:
// [[[NSURLConnection alloc]initWithRequest:request delegate:self]autorelease];
// 建立连接 方法 2:
// 使用这个方法 不用指定代理 但是可以创建线程
// 创建一个
NSOperationQueue *queue = [[ NSOperationQueue alloc ] init ];
[ NSURLConnection sendAsynchronousRequest :request queue :queue completionHandler :^( NSURLResponse *response, NSData *data, NSError *connectionError) {
// 这里要指定 在数据请求结束之后要做的事情 data 是请求的完整数据 connectionError 是网络连接的错误
// 即在 connectionDidFinishLoading 中做的事情
// 这个参数是个 block 相当于苹果对于异步请求的一个封装 但是用这种方法无法显示进度
// 所以如果要显示进度 就要自己使用 方法 1 去执行代理方法
NSMutableDictionary *dic = [ NSJSONSerialization JSONObjectWithData :data options : NSJSONReadingMutableContainers error : nil ];
NSLog ( @"%@" ,dic);
}];
}
- ( void )connection:( NSURLConnection *)connection didReceiveResponse:( NSURLResponse *)response
{
self . receiverData = [ NSMutableData data ];
/*
// 获取 response 信息
NSLog(@"%@",response);
// 有的 response 中没有 contentlength 这个字段 这时候就无法获取内容长度大小
// 获取请求的的数据的长度
_contentLength = [response expectedContentLength];
*/
}
- ( void )connection:( NSURLConnection *)connection didReceiveData:( NSData *)data
{
[ self . receiverData appendData :data];
/*
// 求当前已经获取的数据的大小
NSUInteger currentLenth = [self.receiverData length];
// 求进度比例
float progress = 1.0*currentLenth / _contentLength;
// 可以设置进度条的进度
//UIProgressView *progressView = [[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleDefault];
//progressView.progress = progress;
//_progressView.progress = progress;
*/
}
- ( void )connectionDidFinishLoading:( NSURLConnection *)connection
{
NSDictionary *dic = [ NSJSONSerialization JSONObjectWithData : self . receiverData options : NSJSONReadingMutableContainers error : nil ];
NSArray *newsArray = [dic objectForKey : @"news" ];
for ( NSDictionary *newDic in newsArray) {
NewsInfo *newsInfo = [[ NewsInfo alloc ] init ];
[newsInfo setValuesForKeysWithDictionary :newDic];
[ self . newsMutableArray addObject :newsInfo];
[newsInfo release ];
}
NSLog ( @"%@" , self . newsMutableArray );
}
- ( void )connection:( NSURLConnection *)connection didFailWithError:( NSError *)error
{
}
- ( void )dealloc {
[ _progressView release ];
[ super dealloc ];
}
@end