iOS-NSURLSession类及代理使用详解
NSURLSession—-iOS7.0以后
特点:
1.支持后台运行
2.暂停,停止,重启,方便
3.下载,断点续传,异步下载
4.上传,异步上传
5.可获取下载,上传的进度
NSURLSession可以发起一下三种任务:
1.DataTask 除了上传下载剩下的都用这个
2.UploadTak 上传时使用的任务
3.DownloadTask 下载时使用的任务
NSURLSessionCOnfigration配置请求的信息
获取单利方式
//获取单例对象,这个单利对象是系统单例(开启一个进程,整个系统共享这个单例)
NSURLSession* session = [NSURLSession sharedSession];
DataTask演示
GET请求
NSURL *url = [NSURL URLWithString:@"这里是网址,注意要协议头"];
//单利,单独的进程。所有APP全部可以用
NSURLSession *session = [NSURLSession sharedSession];
//任务默认都是挂起的
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//把JSON数据转化成字典或数组
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
//打印
NSLog(@"%@",json);
}];
//开始任务
[dataTask resume];
POST请求下载
NSURL *url = [NSURL URLWithString:@"这里是网址,注意要协议头"];
//可变的request对象设置
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//post方式
request.HTTPMethod = @"post";
//请求体
NSString *body = @"username=123&password=123";
request.HTTPBody = [body dataUsingEncoding:NSUTF8StringEncoding];
[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//数据解析
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
NSLog(@"%@",json);
//开始任务
}] resume];
下载文件显示下载进度(代理NSURLSessionDownloadDelegate)
控制器遵守NSURLSessionDownloadDelegate代理
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
//如果设置代理,不能使用回调,否则代理的方法不执行
[[self.session downloadTaskWithURL:url completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"%@",[NSThread currentThread]);
NSLog(@"--下载完成 : %@",location);
}] resume];
下面是代理方法:
//代理方法
//下载完成
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
NSLog(@"%@",[NSThread currentThread]);
NSLog(@"下载完成 : %@",location);
}
//续传的方法
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes {
NSLog(@"续传");
}
//获取进度的方法
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
float process = totalBytesWritten * 1.0 /totalBytesExpectedToWrite;
NSLog(@"下载进度: %f",process);
}
这里需要注意的是设置了代理方法后,创建session时的block是不会执行的.
断点下载,断点续传
断点下载就是在下载的基础上加上下面的代码,这里用
//暂停下载
- (IBAction)pause:(id)sender {
[self.downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
//保存续传的数据
self.resumeData = resumeData;
//把续传数据保存到沙盒中命名为123.tmp
NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:@"123.tmp"];
[self.resumeData writeToFile:path atomically:YES];
NSLog(@"%@",path);
//将任务清空
self.downloadTask = nil;
// NSLog(@"%@",resumeData);
}];
}
//继续下载
- (IBAction)resume:(id)sender {
if (self.downloadTask != nil) {
return;
}
//从沙盒中获取续传数据
NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:@"123.tmp"];
//判断文件是否存在
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:path]) {
//加载已经下好的数据
self.resumeData = [NSData dataWithContentsOfFile:path];
}
if (self.resumeData == nil) {
return;
}
//开始续传
self.downloadTask = [self.session downloadTaskWithResumeData:self.resumeData];
[self.downloadTask resume];
//已经开始续传了,将任务清空,以免重复点击出错
self.resumeData = nil;
}
上传数据与上传进度
这里使用的是PUT方式上传数据
需要权限
//Authorization: Basic YWRtaW46MTIzNDU2
//YWRtaW46MTIzNDU2 表示 admin:123456
上传的方法:
//上传一张大图片
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/uploads/123.jpg"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"put";
//设置账号和密码
//Authorization: Basic YWRtaW46MTIzNDU2
//YWRtaW46MTIzNDU2 admin:123456
[request setValue:[self getAuth:@"admin" pwd:@"123456"] forHTTPHeaderField:@"Authorization"];
//本地文件
NSURL *fileUrl = [[NSBundle mainBundle] URLForResource:@"01.jpg" withExtension:nil];
//上传方法一
// [[self.session uploadTaskWithRequest:request fromFile:fileUrl] resume];
//上传方法二 带block
[[self.session uploadTaskWithRequest:request fromFile:fileUrl completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//输出上传结果
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"--上传完成%@",response);
}] resume];
//获取授权的字符串
- (NSString *)getAuth:(NSString *)name pwd:(NSString *)pwd {
//拼字符串 admin:123456
NSString *tmpStr = [NSString stringWithFormat:@"%@:%@",name,pwd];
//base64编码
tmpStr = [self base64Encode:tmpStr];
//Basic YWRtaW46MTIzNDU2
return [NSString stringWithFormat:@"Basic %@",tmpStr];
}
上传代理方法,上传可以用NSURLSessionTaskDelegate代理也可以用NSURLSessionTaskDelegate和NSURLSessionDownloadDelegate都可以.
其实只需要用到NSURLSessionTaskDelegate这个代理的方法就够了,NSURLSessionTaskDelegate和NSURLSessionDownloadDelegate都继承于NSURLSessionTaskDelegate
这里需要注意的是,这个代理方法和block方法都存在的时候,只会执行block里面的方法,这里正好与上面的download正好相反
//上传需要遵守NSURLSessionTaskDelegate代理
//代理方法
//上传进度
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend {
float progress = totalBytesSent * 1.0 / totalBytesExpectedToSend;
NSLog(@"上传进度 %f",progress);
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
NSLog(@"上传完成");
}
delete请求
delele请求十分简单request.HTTPMethod = @”delete”就行了.
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/uploads/head1.png"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"delete";
//设置账号和密码
// [request setValue:[self getAuth:@"admin" pwd:@"123456"] forHTTPHeaderField:@"Authorization"];
[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSString *str= [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
//204 状态码 执行成功,什么都不返回
NSLog(@"-- %@",str);
NSLog(@"%@",response);
}] resume];