image View显示下载的图片
Lable:显示下载进度
progress View:用来显示下载进度
Resume按钮:下载开始
Pause按钮:停止下载
Cancle:下载取消
2.
DataTaskViewController
#import "ViewController.h"
@interface DataTaskViewController : ViewController
(weak, nonatomic) IBOutletUIImageView *imageView;
(weak, nonatomic) IBOutletUILabel *progressLabel;
(weak, nonatomic) IBOutletUIProgressView *progressView;
(weak, nonatomic) IBOutletUIButton *resumeButton;
(weak, nonatomic) IBOutletUIButton *pauseButton;
(weak, nonatomic) IBOutletUIButton *cancleButton;
@end
================================================================================
3.在DataTaskViewController.m
代码:
#import "DataTaskViewController.h"
@interface DataTaskViewController ()<NSURLSessionDelegate,NSURLSessionDataDelegate,NSURLSessionTaskDelegate>//一般写三个方法但三个协议里面的方法我们不一定会用
{//把响应的属性设置为全局变量
NSMutableData *mdata;//可变数据
NSURLSession
NSURLSessionDataTask *dataTask;
NSUInteger
}
@end
@implementation
void)viewDidLoad {
[superviewDidLoad];
/*
NSURLSessionConfiguration
用于配置会话的属性,可以通过该类配置会话的工作模式,他有三种工作方式:
1.默认会话模式(default):工作模式类似于原来的NSURLConnction,使用的时基于磁盘缓存的持久化策略,使用用户keychain中保存的证书进行认证授权;
2.瞬时会话模式(eohemeral)该模式不使用磁盘保存任何数据,所有和会话相关的caches,证书,cookies等都被保存在RAM中,因为当此程序是会话五小时,这些缓存的数据就会被自动清空。
3,后台会话模式(background):该模式在后台完成上传和下载,在chuangjianconfiguration对象的时候需要提供一个NSString类型的ID来标识完成工作后台的会话。
+ (NSURLSessionConfiguration *)defaultSessionConfiguration;
+ (NSURLSessionConfiguration *)ephemeralSessionConfiguration;
+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier NS_AVAILABLE(10_10, 8_0);
*/
//配置会话环境
NSURLSessionConfiguration *configuration=[NSURLSessionConfigurationephemeralSessionConfiguration];
//创建一个NSURLSession
//NSURLSession
/*
使用静态shareSession方法,该类使用共享的话,该会话使用全局的Cache,Cookie
+ (NSURLSession *)sharedSession;
创建对应配置的会话,与NSURLSessionConfiguration结合使用
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration;
//创建一个新会话并指定器会话类型,该方式中指定了session得委托和委托所处的队列。
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id <NSURLSessionDelegate>)delegate delegateQueue:(nullable NSOperationQueue *)queue;
*/
_session=[NSURLSessionsessionWithConfiguration:configuration delegate:selfdelegateQueue:[NSOperationQueuemainQueue]];//主线程
/*
类
是一个抽象类,它有三个类:
和NSURLSessionDownloadTask。这三个类封装了现代应用程序的三个基本网络任务,获取数据没比如JSON和XML以及上传和下载文件。
NSURLSessionDataTask
通过request对象或者url创建
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request;
- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url;
*/
//为给定的URL创建检索任务,是用NSURLSessionDataTask来检索任务
dataTask=[_sessiondataTaskWithURL:[NSURLURLWithString:@"http://img5q.duitang.com/uploads/item/201410/23/20141023133538_FKFhe.jpeg"]];
self.progressView.progress=0;
}
//断点续传
IBAction)resume:(id)sender
{
if (dataTask.state==NSURLSessionTaskStateSuspended)
{
//加载
[dataTaskresume];//NSURLSessionDataTask继承NSURLSessionTask的类在调用resume方法开始
self.resumeButton.enabled =NO;//按钮不可以
self.pauseButton.enabled=YES;
self.cancleButton.enabled=YES;
}
}
==============================注意这里是上面的方法的更改=================================
/*
如果按照刚刚写的-(IBAction)resume:(id)sender
方法图片的不能适配ImageView
*/
IBAction)resume:(id)sender
{
if (dataTask.state==NSURLSessionTaskStateSuspended)
{
//加载
[dataTaskresume];//NSURLSessionDataTask继承NSURLSessionTask的类在调用resume方法开始
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
self.resumeButton.enabled =NO;//按钮不可以
self.pauseButton.enabled=YES;
self.cancleButton.enabled=YES;
}
}
===================================================================
IBAction)pause:(id)sender
{
if (dataTask.state==NSURLSessionTaskStateRunning)
{
[dataTasksuspend];//NSURLSessionDataTask继承NSURLSessionTask的类在调用suspend方法开始
self.pauseButton.enabled=NO;
self.resumeButton.enabled=YES;
self.cancleButton.enabled=YES;
}
}
IBAction)cancle:(id)sender
{
//不管是暂停和运行都可以取消
/*
@property (readonly) NSURLSessionTaskState state;
是一个枚举类型
typedef NS_ENUM(NSInteger, NSURLSessionTaskState)
{
NSURLSessionTaskStateRunning = 0, //The task is currently being serviced by the session
NSURLSessionTaskStateSuspended = 1,
NSURLSessionTaskStateCanceling = 2, // The task has been told to cancel. The session will receive a URLSession:task:didCompleteWithError: message.
NSURLSessionTaskStateCompleted = 3, // The task has completed and the session will receive no more delegate notifications
} NS_ENUM_AVAILABLE(NSURLSESSION_AVAILABLE, 7_0);
*/
switch (dataTask.state)
{
caseNSURLSessionTaskStateRunning:
caseNSURLSessionTaskStateSuspended:
{
dataTask cancel];
self.cancleButton.enabled=NO;
self.resumeButton.enabled=NO;
self.pauseButton.enabled=NO;
}
break;
default:
break;
}
}
//任务收到响应
void)URLSession:(NSURLSession
NSURLSessionDataTask
NSURLResponse
void (^)(NSURLSessionResponseDisposition))completionHandler
{
/*
这个主要判断是否有数据
*/
expectLenth = response.expectedContentLength;//存放数据长度
if (expectLenth != -1)//有数据时
{
NSURLSessionResponseAllow);//继续传输数据
mdata = [NSMutableDatadata];//创建一个数据
else
/*
没有数据没有必要传输
*/
completionHandler(NSURLSessionResponseCancel);//如果response里不包括数据长度信息,就取消数据传输
NSLog(@"response里面不包括数据长度信息,就取消数据传输");
}
}
//收到数据时回调的方法
void)URLSession:(NSURLSession
NSURLSessionDataTask
NSData
{
mdata appendData:data];
float progress=(float)mdata.length/(float)expectLenth;//数据总长度加/传输数据的长度
self.progressView.progress=progress;//进度条
self.progressLabel.text=[NSStringstringWithFormat:@"%.1f%@",progress*100,@"%"];//在Label框内显示百分比
NSLog(@"%f",progress);
//NSLog(@"%lu",mdata.length);
}
#pragma mark----------------NSURLSessionTaskDelegate------
//task完成时实现的方法
void)URLSession:(NSURLSession *)session task:(NSURLSessionTask
nullable NSError
{
[_sessionfinishTasksAndInvalidate]; //完成task就invalidate
if
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *image=[UIImageimageWithData:mdata];//把数据转换成图片
self.imageView.image=image;//把转换出来的图片传给Image View
_session=nil;//对没用的类型设置为空
dataTask=nil;
mdata=nil;
});
}
else
{
NSLog(@"error = %@",error.debugDescription);//打印错误信息
}
}
//=====
void)didReceiveMemoryWarning {
[superdidReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
=================================================================================
运行: