web123456

iOS Web Development NSURLSession (II) DataTask + Demo

#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