#import ""
@interface ViewController ()<NSURLSessionDelegate,NSURLSessionTaskDelegate,NSURLSessionDataDelegate>
@property (strong,nonatomic)UIImageView * imageview;
@property (strong,nonatomic)NSURLSession * session;
@property (strong,nonatomic)NSURLSessionDataTask * dataTask;
@property (weak, nonatomic) IBOutlet UIProgressView *progressview;
@property (nonatomic)NSUInteger expectlength;
@property (strong,nonatomic) NSMutableData * buffer;
@end
static NSString * imageURL = @"/o129/";
@implementation ViewController
// Properties are all initialized with inertia.
#pragma mark - lazy property
-(UIImageView *)imageview{
if (!_imageview) {
_imageview = [[UIImageView alloc] initWithFrame:CGRectMake(40,40,300,200)];
_imageview.backgroundColor = [UIColor lightGrayColor];
_imageview.contentMode = UIViewContentModeScaleToFill;
}
return _imageview;
}
-(NSMutableData *)buffer{
if (!_buffer) {
_buffer = [[NSMutableData alloc] init];
}
return _buffer;
}
-(NSURLSession*)session{
if (!_session) {
NSURLSessionConfiguration * configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration];
_session = [NSURLSession sessionWithConfiguration:configuration
delegate:self
delegateQueue:[NSOperationQueue mainQueue]];
}
return _session;
}
-(NSURLSessionDataTask *)dataTask{
if (!_dataTask) {
_dataTask = [self.session dataTaskWithURL:[NSURL URLWithString:imageURL]];
}
return _dataTask;
}
#pragma mark - life circle of viewcontroller
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.imageview];
[self.dataTask resume];//Task to RESUME coloring for actual data transfer
[self.session finishTasksAndInvalidate];//invalidate on completion of task
}
#pragma mark - target-action
// Note that determining the state of the current Task
- (IBAction)pause:(UIButton *)sender {
if (self.dataTask.state == NSURLSessionTaskStateRunning) {
[self.dataTask suspend];
}
}
- (IBAction)cancel:(id)sender {
switch (self.dataTask.state) {
case NSURLSessionTaskStateRunning:
case NSURLSessionTaskStateSuspended:
[self.dataTask cancel];
break;
default:
break;
}
}
- (IBAction)resume:(id)sender {
if (self.dataTask.state == NSURLSessionTaskStateSuspended) {
[self.dataTask resume];
}
}
#pragma mark - URLSession delegate method
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{
NSUInteger length = [response expectedContentLength];
if (length != -1) {
self.expectlength = [response expectedContentLength];//store the total length of data to be transmitted
completionHandler(NSURLSessionResponseAllow);//Continue data transfer
}else{
completionHandler(NSURLSessionResponseCancel);// If the Response does not include information about the length of the data, cancel the data transfer.
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"error"
message:@"Do not contain property of expectedlength"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
}
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{
[self.buffer appendData:data];//Data to be placed in the buffer
self.progressview.progress = [self.buffer length]/((float) self.expectlength);//Change the progress of the progressview.
}
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
if (!error) {
dispatch_async(dispatch_get_main_queue(), ^{// Use GCD to ensure that the UI is updated on the main thread
UIImage * image = [UIImage imageWithData:self.buffer];
self.imageview.image = image;
self.progressview.hidden = YES;
self.session = nil;
self.dataTask = nil;
});
}else{
NSDictionary * userinfo = [error userInfo];
NSString * failurl = [userinfo objectForKey:NSURLErrorFailingURLStringErrorKey];
NSString * localDescription = [userinfo objectForKey:NSLocalizedDescriptionKey];
if ([failurl isEqualToString:imageURL] && [localDescription isEqualToString:@"cancelled"]) {//If it's a task that's been canceled, pop up the alert box
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Message"
message:@"The task is canceled"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}else{
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Unknown type error"//other errors, then popup error description
message:error.localizedDescription
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
self.progressview.hidden = YES;
self.session = nil;
self.dataTask = nil;
}
}
@end