一. NSURLConnection常用方法(已弃用)
1.0 简介
NSURLConnection 是 2003 年 iOS 2.0 随着第一版 Safari 的发布而发布的,它不单单是一个网络请求类,而是指代 Foundation 框架的 URL 系统中的一系列关联的组件: NSURLRequest、NSURLResponse、NSURLProtocol、NSHTTPCookieStorage、NSURLCredentialStorage 以及同名类 NSURLConnection。
1.1 常用类
- NSURL:请求地址
- NSURLRequest:一个NSURLRequest对象就代表一个请求,, NSMutableURLReques是它的子类, 它包含的信息有
- 一个NSURL对象
- 请求方法、请求头、请求体
- 请求超时… …
- NSURLConnection
- 负责发送请求,建立客户端和服务器的连接
- 发送数据给服务器,并收集来自服务器的响应数据
1.2 使用步骤
-
创建一个NSURL对象,设置请求路径
-
传入NSURL创建一个NSURLRequest对象,设置请求头和请求体
-
使用NSURLConnection发送请求
1.3 NSURLRequest
设置请求超时等待时间(超过这个时间就算超时,请求失败)
- (void)setTimeoutInterval:(NSTimeInterval)seconds;
设置请求方法(比如GET和POST)
- (void)setHTTPMethod:(NSString *)method;
设置请求体
- (void)setHTTPBody:(NSData *)data;
设置请求头
- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field;
1.3 发送请求
- 同步请求
+ (nullable NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse * _Nullable * _Nullable)response error:(NSError **)error;
- 异步请求:根据对服务器返回数据的处理方式的不同,又可以分为2种
// block回调
+ (void)sendAsynchronousRequest:(NSURLRequest*) request queue:(NSOperationQueue*) queue completionHandler:(void (^)(NSURLResponse* response, NSData* data, NSError* connectionError)) handler;
// 代理
- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate;
+ (NSURLConnection*)connectionWithRequest:(NSURLRequest *)request delegate:(id)delegate;
- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately;
在startImmediately = NO的情况下,需要调用start方法开始发送请求
- (void)start;
成为NSURLConnection的代理,要好遵守NSURLConnectionDataDelegate协议
<NSURLConnectionDataDelegate>协议中的代理方法
开始接收到服务器的响应时调用
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
接收到服务器返回的数据时调用(服务器返回的数据比较大时会调用多次)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
服务器返回的数据完全接收完毕后调用
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
请求出错时调用(比如请求超时)
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
二. NSURLConnection网络请求
1.4 示例: get请求
- (void)getNetwork
{
// 1.0 url
NSURL *url = [NSURL URLWithString:@"https://apitest3.drstrong.cn/health-cure/cure/consult/count/not-handle?doctorId=35573&token=e8dc2e74694df8689089&ucDoctorId=625371"];
// 2.0 创建请求体
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
// 2.1 设置header
[request setValue:@"13979af4eda34f70a305c70a0cb86c7b" forHTTPHeaderField:@"token"];
// 3.0 同步请求
NSHTTPURLResponse *response = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
NSLog(@"%zd",response.statusCode);
// 3.0 异步请求
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
//4.解析数据
NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;
NSLog(@"%zd",res.statusCode);
NSLog(@"%@",[NSThread currentThread]);
}];
}
1.5 示例: post表单请求
- (void)postFromNetWork
{
// 1.0 确定请求路径
NSURL *url = [NSURL URLWithString:@"https://apitest3.drstrong.cn/health-doctor/checkVersion"];
// 2.0 创建可变请求对象
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
// 2.1 修改请求方法,POST必须大写
[request setHTTPMethod:@"POST"];
// 2.2 设置属性, 请求超时
request.timeoutInterval = 5;
// 2.3 设置header
[request setValue:@"13979af4eda34f70a305c70a0cb86c7b" forHTTPHeaderField:@"token"];
// 设置请求的格式from类型, 默认可以不设置
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
// 2.4 设置请求体
request.HTTPBody = [@"doctorId=35573&paltform=iphone&token=e8dc2e74694df8689089&version=2.3.1" dataUsingEncoding:NSUTF8StringEncoding];
// 3.0 异步请求
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
//4.解析数据
NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;
NSLog(@"%zd",res.statusCode);
NSLog(@"%@",[NSThread currentThread]);
}];
}
1.6 示例: postJson请求
- (void)postJsonNetWork
{
// 1.0 确定请求路径
NSURL *url = [NSURL URLWithString:@"https://apitest3.drstrong.cn/health-im/im/group/infosNew?token=e8dc2e74694df8689089&doctorId=35573"];
// 2.0 创建可变请求对象
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
// 2.1 修改请求方法,POST必须大写
[request setHTTPMethod:@"POST"];
// 2.2 设置属性, 请求超时
request.timeoutInterval = 5;
// 2.3 设置header
[request setValue:@"13979af4eda34f70a305c70a0cb86c7b" forHTTPHeaderField:@"token"];
// 设置请求的格式json类型, 必须要设置
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
// 2.4 设置请求体
NSMutableDictionary *bodyDic = [NSMutableDictionary dictionary];
bodyDic[@"identityType"] = @"1";
bodyDic[@"empty"] = @(NO);
bodyDic[@"doctorId"] = @"35573";
bodyDic[@"token"] = @"e8dc2e74694df8689089";
bodyDic[@"groupIds"] = @"171565222264834,170922752409603";
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:bodyDic options:kNilOptions error:nil];
request.HTTPBody = jsonData;
// 3.0 异步请求
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
//4.解析数据
NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;
NSLog(@"%zd",res.statusCode);
NSLog(@"%@",[NSThread currentThread]);
}];
}
1.7 示例: 代理请求
- (void)useSessionDelegate
{
// 1.0 确定请求路径
NSURL *url = [NSURL URLWithString:@"https://apitest3.drstrong.cn/health-doctor/checkVersion"];
// 2.0 创建可变请求对象
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
// 2.1 修改请求方法,POST必须大写
[request setHTTPMethod:@"POST"];
// 2.2 设置属性, 请求超时
request.timeoutInterval = 5;
// 2.3 设置header
[request setValue:@"7b203782da1f4c50ba7e52cec9901b8a" forHTTPHeaderField:@"token"];
// 设置请求的格式from类型, 默认可以不设置
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
// 2.4 设置请求体
request.HTTPBody = [@"doctorId=35573&paltform=iphone&token=e8dc2e74694df8689089&version=2.3.1" dataUsingEncoding:NSUTF8StringEncoding];
// 3.0 异步请求
NSURLConnection *connect = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
// 4.0 执行
[connect start];
}
#pragma mark NSURLConnectionDataDelegate
//1.当接收到服务器响应的时候调用
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(@"%s",__func__);
}
//2.接收到服务器返回数据的时候调用,调用多次
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(@"%s",__func__);
//拼接数据
NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
}
//3.当请求失败的时候调用
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"%s",__func__);
}
//4.请求结束的时候调用
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@"%s",__func__);
}
三. 文件下载
1.0 示例: 下载(利用NSFileHandle句柄文件创建)
-(void)download3
{
NSURL *url = [NSURL URLWithString:@"http://www.33lc.com/article/UploadPic/2012-10/2012102514201759594.jpg"];
//2.创建请求对象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//设置请求头信息,告诉服务器值请求一部分数据range
/*
bytes=0-100 表示: 下载0到100个字节
bytes=-100 表示: 下载最后100个字节
bytes=50- 表示: 下载50个字节以后的所有数据
*/
NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.currentSize];
[request setValue:range forHTTPHeaderField:@"Range"];
NSLog(@"+++++++%@",range);
//3.发送请求
NSURLConnection *connect = [[NSURLConnection alloc]initWithRequest:request delegate:self];
self.connect = connect;
}
#pragma mark NSURLConnectionDataDelegate
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(@"didReceiveResponse");
//1.得到文件的总大小(本次请求的文件数据的总大小 != 文件的总大小)
// self.totalSize = response.expectedContentLength + self.currentSize;
if (self.currentSize >0) {
return;
}
self.totalSize = response.expectedContentLength;
//2.写数据到沙盒中
self.fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]stringByAppendingPathComponent:@"123.jpg"];
NSLog(@"%@",self.fullPath);
//3.创建一个空的文件
[[NSFileManager defaultManager] createFileAtPath:self.fullPath contents:nil attributes:nil];
//NSDictionary *dict = [[NSFileManager defaultManager]attributesOfItemAtPath:self.fullPath error:nil];
//4.创建文件句柄(指针)
self.handle = [NSFileHandle fileHandleForWritingAtPath:self.fullPath];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
//1.移动文件句柄到数据的末尾
[self.handle seekToEndOfFile];
//2.写数据
[self.handle writeData:data];
//3.获得进度
self.currentSize += data.length;
//进度=已经下载/文件的总大小
NSLog(@"%f",1.0 * self.currentSize/self.totalSize);
self.progressView.progress = 1.0 * self.currentSize/self.totalSize;
//NSLog(@"%@",self.fullPath);
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//1.关闭文件句柄
[self.handle closeFile];
self.handle = nil;
NSLog(@"connectionDidFinishLoading");
NSLog(@"%@",self.fullPath);
}
1.1 示例: 下载(利用NSOutputStream输出流创建)
#pragma mark NSURLConnectionDataDelegate
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(@"didReceiveResponse");
//1.得到文件的总大小(本次请求的文件数据的总大小 != 文件的总大小)
// self.totalSize = response.expectedContentLength + self.currentSize;
if (self.currentSize >0) {
return;
}
self.totalSize = response.expectedContentLength;
//2.写数据到沙盒中
self.fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]stringByAppendingPathComponent:@"123.jpg"];
NSLog(@"%@",self.fullPath);
//3.创建输出流
// NSOutputStream
// NSInputStream
/*
第一个参数:文件的路径
第二个参数:YES 追加
特点:如果该输出流指向的地址没有文件,那么会自动创建一个空的文件
*/
NSOutputStream *stream = [[NSOutputStream alloc]initToFileAtPath:self.fullPath append:YES];
//打开输出流
[stream open];
self.stream = stream;
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
//写数据
[self.stream write:data.bytes maxLength:data.length];
//3.获得进度
self.currentSize += data.length;
//进度=已经下载/文件的总大小
NSLog(@"%f",1.0 * self.currentSize/self.totalSize);
self.progressView.progress = 1.0 * self.currentSize/self.totalSize;
//NSLog(@"%@",self.fullPath);
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//关闭流
[self.stream close];
self.stream = nil;
NSLog(@"connectionDidFinishLoading");
NSLog(@"%@",self.fullPath);
}
四. 文件上传
1.1 文件上传的步骤
设置请求头
[request setValue:@"multipart/form-data; boundary=分割线" forHTTPHeaderField:@"Content-Type"];
设置请求体
非文件参数
--分割线\r\n
Content-Disposition: form-data; name="参数名"\r\n
\r\n
参数值
\r\n
文件参数
--分割线\r\n
Content-Disposition: form-data; name="参数名"; filename="文件名"\r\n
Content-Type: 文件的MIMEType\r\n
\r\n
文件数据
\r\n
参数结束的标记
--分割线--\r\n
1.2 部分文件的MIMEType
| 类型 | 文件拓展名 | MIMEType |
|---|---|---|
| 图片 | png | image/png |
| bmp\dib | image/bmp | |
| jpe\jpeg\jpg | image/jpeg | |
| gif | image/gif | |
| 多媒体 | mp3 | audio/mpeg |
| mp4\mpg4\m4vmp4v | video/mp4 | |
| 文本 | js | application/javascript |
| application/pdf | ||
| text\txt | text/plain | |
| json | application/json | |
| xml | text/xml |
1.3 获取MIMEType
// 利用NSURLConnection
- (NSString *)MIMEType:(NSURL *)url
{
// 1.创建一个请求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 2.发送请求(返回响应)
NSURLResponse *response = nil;
[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
// 3.获得MIMEType
return response.MIMEType;
}
C语言API
+ (NSString *)mimeTypeForFileAtPath:(NSString *)path
{
if (![[NSFileManager alloc] init] fileExistsAtPath:path]) {
return nil;
}
CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (CFStringRef)[path pathExtension], NULL);
CFStringRef MIMEType = UTTypeCopyPreferredTagWithClass (UTI, kUTTagClassMIMEType);
CFRelease(UTI);
if (!MIMEType) {
return @"application/octet-stream";
}
return NSMakeCollectable(MIMEType);
}
1.4 示例: 上传代码
#define Kboundary @"Boundary+E290ED5D8ABB1606"
#define KNewLine [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]
- (void)postFromNetWork
{
// 1.0 确定请求路径
NSURL *url = [NSURL URLWithString:@"https://apitest3.drstrong.cn/health-doctor/feedback/uploadFeedbackImg"];
// 2.0 创建可变请求对象
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
// 2.1 修改请求方法,POST必须大写
[request setHTTPMethod:@"POST"];
// 2.2 设置属性, 请求超时
request.timeoutInterval = 5;
// 2.3 设置header
[request setValue:@"990472e1ff8146fca638597f5f0e51d2" forHTTPHeaderField:@"token"];
// 2.4设置请求的格式为上传类型
[request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary] forHTTPHeaderField:@"Content-Type"];
// 2.5 设置请求体
// 2.5.1 文件参数
NSMutableData *fileData = [NSMutableData data];
/**
--Boundary+E290ED5D8ABB1606
Content-Disposition: form-data; name="file"; filename="imgFile"
Content-Type: image/png
@¿±:Ì=ºÃûNþ^-zêo¾ô¾g¿óÄ^zóO|çUýíB
ê»ï¥§^tOyå®i^otfö×ó¾/·Ð%§,Q[íóz³*Ó~^fÊ
--Boundary+E290ED5D8ABB1606
Content-Disposition: form-data; name="token"
e8dc2e74694df8689089
--Boundary+E290ED5D8ABB1606--
*/
[fileData appendData:[[NSString stringWithFormat:@"--%@", Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine]; // 换行
[fileData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=%@; filename=%@", @"file", @"imgFile"] dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine]; // 换行
[fileData appendData:[@"Content-Type: image/png" dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine]; // 换行
[fileData appendData:KNewLine]; // 换行
UIImage *image = [UIImage imageNamed:@"杭州盘石信息技术有限公司996制度.png"];
NSData *imageData = UIImagePNGRepresentation(image);
[fileData appendData:imageData];
[fileData appendData:KNewLine]; // 换行
/**
2.5.2 非文件参数
--Boundary+E290ED5D8ABB1606
Content-Disposition: form-data; name="token"
e8dc2e74694df8689089
*/
[fileData appendData:[[NSString stringWithFormat:@"--%@", Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine]; // 换行
[fileData appendData:[@"Content-Disposition: form-data; name=\"token\"" dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine]; // 换行
[fileData appendData:KNewLine]; // 换行
[fileData appendData:[@"e8dc2e74694df8689089" dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine]; // 换行
/**
2.5.3 结尾标识
--Boundary+E290ED5D8ABB1606--
*/
[fileData appendData:[[NSString stringWithFormat:@"--%@--", Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
// 2.6 设置请求体
request.HTTPBody = fileData;
// 3.0 异步请求
NSURLConnection *connect = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
[connect start];
}