Search code examples
iosobjective-cuiimageviewnsurlsessionnsurlsessiondownloadtask

Using NSURLSessionDownloadTask to display an image


I was wondering if someone could help me out. I'm trying to use NSURLSessionDownloadTask to display a picture in my UIImageView if I put the image URL into my textfield.

-(IBAction)go:(id)sender { 
     NSString* str=_urlTxt.text;
     NSURL* URL = [NSURL URLWithString:str];
     NSURLRequest* req = [NSURLRequest requestWithURL:url];
     NSURLSession* session = [NSURLSession sharedSession];
     NSURLSessionDownloadTask* downloadTask = [session downloadTaskWithRequest:request];
}

I am not sure where to go after this.


Solution

  • Two options:

    1. Use [NSURLSession sharedSession], with rendition of downloadTaskWithRequest with the completionHandler. For example:

      typeof(self) __weak weakSelf = self; // don't have the download retain this view controller
      
      NSURLSessionTask* downloadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
      
          // if error, handle it and quit
      
          if (error) {
              NSLog(@"downloadTaskWithRequest failed: %@", error);
              return;
          }
      
          // if ok, move file
      
          NSFileManager *fileManager = [NSFileManager defaultManager];
          NSURL *documentsURL = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0];
          NSURL *fileURL = [documentsURL URLByAppendingPathComponent:filename];
          NSError *moveError;
          if (![fileManager moveItemAtURL:location toURL:fileURL error:&moveError]) {
              NSLog(@"moveItemAtURL failed: %@", moveError);
              return;
          }
      
          // create image and show it im image view (on main queue)
      
          UIImage *image = [UIImage imageWithContentsOfFile:[fileURL path]];
          if (image) {
              dispatch_async(dispatch_get_main_queue(), ^{
                  weakSelf.imageView.image = image;
              });
          }
      }];
      [downloadTask resume];
      

      Clearly, do whatever you want with the downloaded file (put it somewhere else if you want), but this might be the basic pattern

    2. Create NSURLSession using session:delegate:queue: and specify your delegate, in which you'll conform to NSURLSessionDownloadDelegate and handle the completion of the download there.

    The former is easier, but the latter is richer (e.g. useful if you need special delegate methods, such as authentication, detecting redirects, etc., or if you want to use background session).

    By the way, don't forget to [downloadTask resume], or else the download will not start.