OC-NSURLSession

来源:互联网 发布:自动化测试软件 编辑:程序博客网 时间:2024/06/07 01:23

NSURLSession的基本概念:

三种工作方式:
默认会话模式(default):工作模式类似于原来的NSURLConnection,使用的是基于磁盘缓存的持久化策略,使用用户keychain中保存的整数进行认证授权。

瞬时会话模式(ephemeral)该模式不实用磁盘保存任何数据。所有和会话相关的caches,证书,cookies等都被保存在RAM中,因此当程序使会话无效,这些缓存的数据就会被自动清空。

后台会话模式(background):该模式在后台完成上传和下载,在创建Configuration对象的时候需要提供一个NSString类型的ID用于标识完成工作的后台会话。

NSURLSession支持的三种任务

加载数据 NSURLSessionDataTask
下载 NSURLSessionDownloadTask
上传 NSURLSessionUploadTask


NSURLSessionDataTask
使用协议实现

- (void)dataTask{    //配置会话属性    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];    //创建任务对象(NSURLSession 使用 代理 或 block)    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue mainQueue]];    //通过url 创建dataTask    NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:@"http://f.hiphotos.baidu.com/image/pic/item/e1fe9925bc315c60d916f9d58ab1cb134954770d.jpg"]];    [dataTask resume];}

书写代理的三个方法

//在书写方法之前,我们定义两个全局变量,分别用来接收数据和计算当前进度,以便创建进度条//在UI上创建一个imgView以及progressView@interface ViewController ()<NSURLSessionDataDelegate>{    NSMutableData *_mData;    NSUInteger _expectedContenLenght;}@property (weak, nonatomic) IBOutlet UIImageView *imgView;@property (weak, nonatomic) IBOutlet UIProgressView *progressView;@end

任务收到响应

- (void)URLSession:(NSURLSession *)  session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response  completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler{    NSLog(@"收到响应");    _mData = [NSMutableData data];    //允许处理服务器的响应,才会继续接收服务器返回的数据    completionHandler(NSURLSessionResponseAllow);    _expectedContenLenght = response.expectedContentLength;}

收到数据时回调的方法

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask    didReceiveData:(NSData *)data{    NSLog(@"收到数据");    [_mData appendData:data];    //    self.progressView.progress = (CGFloat) _mData.length / _expectedContenLenght;}

task完成时实现的方法

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)taskdidCompleteWithError:(NSError *)error{    if (!error) {        //回到主线程更新UI        dispatch_async(dispatch_get_main_queue(), ^{            self.imgView.image = [UIImage imageWithData:_mData];        });    }}

用一个touchesBegan来调用方法

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{    [self dataTask2];}

使用block实现

- (void)dataTask2{    //配置会话属性    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];    //创建任务对象    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];    //通过url创建DataTask    NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:@"http://f.hiphotos.baidu.com/image/pic/item/e1fe9925bc315c60d916f9d58ab1cb134954770d.jpg"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {        if (!error) {            dispatch_async(dispatch_get_main_queue(), ^{                self.imgView.image = [UIImage imageWithData:data];            });        }    }];    [dataTask resume];}

NSURLSessionUploadTask
以微博发送信息为例

- (void)uploadTask{    //配置会话模式    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];    //将string编码后转成url    NSString *urlString = @"https://api.weibo.com/2/statuses/update.json";    urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];    NSURL *url = [NSURL URLWithString:urlString];    //创建任务对象    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];    NSMutableURLRequest *mRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:60];    NSString *bodyString = [NSString stringWithFormat:@"access_token=填入微博的相关API&status=%@",self.textField.text];    NSData *bodyData = [bodyString dataUsingEncoding:4];    [mRequest setHTTPMethod:@"POST"];    [mRequest setHTTPBody:bodyData];    NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:mRequest fromData:bodyData completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {        if (!error) {            NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];            NSLog(@"%@",dictionary);        }    }];    [uploadTask resume];}

使用一个按钮来调用方法

- (IBAction)SendAction:(UIButton *)sender {    [self uploadTask];}

NSURLSessionDownloadTask,一般用于大文件下载
使用block实现,之后再用touchesBegan来调用,此处不演示

- (void)downloadTask1{    //创建任务对象    NSURLSession *session = [NSURLSession sharedSession];    //创建下载任务    //文件默认下载到tmp文件夹下,当下载完成后,如果没有做任何处理,会被删除,所以要在下载完成的时候将文件    NSURLSessionUploadTask *downloadTask = [session downloadTaskWithURL:[NSURL URLWithString:@"http://c.hiphotos.baidu.com/image/pic/item/023b5bb5c9ea15ce9c017233b1003af33a87b219.jpg"] completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {        if (!error) {            //location.path            NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, 1, YES)objectAtIndex:0];            //建议使用的名字和服务器的名字一样            NSString *fileName = response.suggestedFilename;            NSString *filePath = [cachesPath stringByAppendingString:fileName];            NSFileManager *fileManager = [NSFileManager defaultManager];            [fileManager moveItemAtPath:location.path toPath:filePath error:nil];        }    }];    [downloadTask resume];}

使用协议实现下载以及断点下载

//我们声明三个全局变量,用于在不同方法间使用@property (nonatomic,strong)NSURLSessionDownloadTask *downloadTask;@property (nonatomic,strong)NSData *resumeData;@property (nonatomic,strong)NSURLSession *sessionDownload;
- (void)downloadTask2{    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];    self.sessionDownload = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue mainQueue]];    self.downloadTask = [self.sessionDownload downloadTaskWithURL:[NSURL URLWithString:@"http://b.zol-img.com.cn/desk/bizhi/image/7/2560x1600/145135666476.jpg"]];    [self.downloadTask resume];}

数据下载完成,此方法为必选方法

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTaskdidFinishDownloadingToURL:(NSURL *)location{    //数据下载完成后保存到caches文件夹下    NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)objectAtIndex:0];    NSString *filePath = [cachesPath stringByAppendingPathComponent:downloadTask.response.suggestedFilename];    NSFileManager *fileManager = [NSFileManager defaultManager];    [fileManager moveItemAtPath:location.path toPath:filePath error:nil];}

此方法用于显示当前下载进度条,此方法为可选方法

/* 每当下载完一部分数据就会走这个方法 session                    任务对象 downloTask                 下载任务 bytesWritten               本次写到文件里面的数据 totalBytesWritten          已经写入到文件的数据 totalBytesExpectedToWrite  文件总长度*/- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{    self.progressView.progress = (CGFloat)totalBytesWritten / totalBytesExpectedToWrite;}

断点下载实现代码

- (IBAction)btnAction:(UIButton *)sender {    if ([sender.titleLabel.text isEqualToString:@"下载"]) {        [sender setTitle:@"暂停" forState:UIControlStateNormal];        if (self.resumeData == nil) {            [self downloadTask2];        }        else{            self.downloadTask = [self.sessionDownload downloadTaskWithResumeData:self.resumeData];            [self.downloadTask resume];        }    }    else{        [sender setTitle:@"下载" forState:UIControlStateNormal];        [self.downloadTask cancelByProducingResumeData:^(NSData *resumeData) {            self.resumeData = resumeData;        }];        self.downloadTask = nil;    }}
0 0