常用类
- NSURL:请求地址
- NSURLRequest:一个NSURLRequest对象就代表一个请求,它包含的信息有
一个NSURL对象
请求方法、请求头、请求体
请求超时 - NSMutableURLRequest:NSURLRequest的子类
- NSURLConnection
负责发送请求,建立客户端和服务器的连接
发送数据给服务器,并收集来自服务器的响应数据
使用步骤
1.创建一个NSURL对象,设置请求路径
2.传入NSURL创建一个NSURLRequest对象,设置请求头和请求体
3.使用NSURLConnection发送请求
GET请求
同步
//1.确定请求路径
NSURL *url = [NSURL URLWithString:@""];
//2.根据URL创建请求对象
//请求头不需要设置(默认的请求头)
//GET请求没有请求体
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
//3.发送请求
//响应的信息将传送回这个参数
NSURLResponse *response = nil;
/*
第一个参数:请求对象
第二个参数:响应头信息
第三个参数:错误信息
返回值:响应体
*/
//同步的,阻塞
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
//4.解析 data---->字符串
//NSUTF8StringEncoding解码模式
NSLog(@"%@" , [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
- NSURLResponse的真实类型是NSHTTPURLResponse,在这个对象下面还会有一些属性
异步
//1.确定请求路径
NSURL *url = [NSURL URLWithString:@""];
//2.根据URL创建请求对象
//请求头不需要设置(默认的请求头)
//默认请求方法---->GET
//GET请求没有请求体
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
//3.发送请求
/*
第一个参数:请求对象
第二个参数:队列 决定代码块的调用线程
第三个参数:completionHandler 当请求完成(成功 | 失败)的时候回调
response:响应头
data:响应体
connectionError:错误信息
*/
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
<#code#>
}];
//4.解析 data---->字符串
//NSUTF8StringEncoding解码模式
NSLog(@"%@" , [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
POST请求
1.确定URL
NSURL *url = [NSURL URLWithString:@""];
2.创建请求对象
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
2.1.设置请求方式
request.HTTPMethod = @"POST";
2.2 设置请求超时
request.timeoutInterval = 10;
2.3 设置请求头(可以不设置)
[request setValue:@"" forHTTPHeaderField:@""];
2.4 设置请求体信息
request.HTTPBody = [@"" dataUsingEncoding:NSUTF8StringEncoding];
3.发送请求(异步)
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
//解析数据
NSLog(@"%@" , [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}];
代理方法发送请求
1.确定URL
NSURL *url = [NSURL URLWithString:@""];
2.创建请求对象
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
3.发送请求(代理方式)
[[NSURLConnection alooc] initWithRequest:request delegate:self];
4.实现代理方法
代理方法
@property(nonatomic,assign) NSInteger totalSize;
@property(nonatomic,strong) NSMutableData *fileData;
- 当接收到服务器响应时调用,response为响应头部
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
//获得文件总大小(本次请求的文件数据的总大小)
self.totalSize = response.expectedContentLength;
}
- 接收到服务返回的数据时调用,多次调用,直至接受到全部数据,每次接受一部分数据,放入到data中
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
//拼接数据并且计算下载进度
[self.fileData appendData:data];
NSLog(@"%f" , 1.0 * self.fileData.length / self.totalSize);
}
- 数据接收完成是调用
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
- 请求错误(失败)的时候调用
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
给发送请求设置代理的多种方法
方法一
NSURLConnection *connection = [[NSURLConnection alooc] initWithRequest:request delegate:self];
如果将该方法放在子线程中,不会调用代理方法,因为没有设置runloop并且将runloop模式设置为默认
方法二(特殊)
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
- 设置完代理就调用代理方法
该方法放在子线程中,会调用代理方法
- 该方法内部其实会将connection对象作为一个source添加到当前的runloop中,指定运行模式为默认
方法三
NSURLConnection *connection = [[NSURLConnection alooc] initWithRequest:request delegate:self startImmediately:YES];
- 最后一个参数传的是否设置完代理就调用代理方法
- 如果最后一个参数是NO,我们还需要手动开始发送请求(调用代理方法)
[connection start];
最后一个参数设置为YES,放在子线程中不会调用代理方法
最后一个参数设置为NO,调用start方法,放在子线程中会调用代理方法
当我们最后一个参数传YES,就不需要调用start方法,如果将这个发送请求的步骤放在子线程中,不会调用代理方法,因为子线程中没有创建runloop,当我们传递NO,我们就需要调用start方法,这个start方法内部还做了一些事情,才让connection调用代理方法
做的事情:
1.如果connection对象没有添加到runloop中,那么该方法内部会自动的添加到runloop
2.如果当前的runloop没有开启,那么该方法内部会自动获得当前线程对应的runloop对象并且开启
取消请求
NSURLConnection *connection = [[NSURLConnection alooc] initWithRequest:request delegate:self];
[connection cancel];
细节
- NSURLConnection发送请求默认是在主线程中发送请求
在子线程中发送请求
NSURLConnection *connect = [NSURLConnection connectionWithRequest:request delegate:self];
//设置代理方法在哪个线程中调用([NSOpertationQueue alloc] init] 开子线程)
[connect setDelegateQueue:[[NSOpertationQueue alloc] init];
- 这个方法不可以设置主队列([NSOpertationQueue mainQueue]),否则不会有任何反应
- 这个设置代理的方法不同于alloc init创建的方法,这个方法(connectionWithRequest:)是设置完代理就调用代理方法