下载大文件NSURLSessionDownloadTask
下载下来的文件会被存放在临时文件夹下,如果不做处理,会被自动删除以节省空间, 需要复制到其他位置.
NSURL *imageURL = [NSURL URLWithString:kImagePath];
//~/Documents/image.png
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"image.png"];
NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithURL:imageURL completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//location下载的文件的存储位置
NSLog(@"location %@", location.path);
//tmp->复制->document下
[[NSFileManager defaultManager] copyItemAtPath:location.path toPath:path error:nil];
NSData *data = [NSData dataWithContentsOfFile:path];
UIImage *image = [UIImage imageWithData:data];
//回到主线程中,设置图片
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
_imageView.image = image;
}];
NSLog(@"path : %@", path);
}];
[task resume];
上传大文件NSURLSessionUploadTask
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"填写服务器地址"]];
NSURL *fileURL = [NSURL URLWithString:@"本地要上传的文件地址"];
NSURLSessionUploadTask *task = [[NSURLSession sharedSession] uploadTaskWithRequest:request fromFile:fileURL completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
}];
[task resume];
任务的暂停
, 取消
, 继续
, 开始
暂停
[dataTask suspend];
取消
[dataTask cancel];
继续和开始
[dataTask resume];
通过代理方式监听网络下载任务进度
可以通过代理的方式,进行网络请求. 这样可以实时监听网络请求的相关状态. 例如上传的进度, 下载的进度, 任务完成情况等.
带有代理的请求任务
@interface ViewController ()<NSURLSessionDataDelegate>
//实时监听下载进度,需要通过代理方法实现
/*
defaultSessionConfiguration:下载的数据存放在tmp临时文件夹下
ephemeralSessionConfiguration:缓存不存放在磁盘,而是在内存中(不推荐)
backgroundSessionConfiguration:网络操作支持后台模式
*/
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
//参数3:代理方法运行的线程,填nil,是在子线程中
NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
_dataTask = [session dataTaskWithURL:[NSURL URLWithString:kImagePath]];
代理方法监听下载任务状态
下载的数据并不是一次性传递的, 而是分批次. 每次的数据大小根据网络情况而定.
需要使用可变的数据类型把这些零散的数据拼接起来.
//当收到数据时触发的,数据是分批次传递,所以此方法会多次触发
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{
[_fileData appendData:data];
UIImage *image = [UIImage imageWithData:_fileData];
dispatch_async(dispatch_get_main_queue(), ^{
//已有数据长度除以总长度, 得到下载百分比
_progressView.progress = dataTask.countOfBytesReceived *1.0/dataTask.countOfBytesExpectedToReceive;
_imageView.image = image;
});
}
//数据请求完毕时
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
//下载完毕以后, 保存下载下来的数据到磁盘中
if (!error) {
[_fileData writeToFile:self.filePath atomically:YES];
}
}