iPhone: How to get a UIImage from a url?

28,482

Solution 1

NSURL *url = [NSURL URLWithString:@"http://example.com/image.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[[UIImage alloc] initWithData:data] autorelease];

However, this isn't asynchronous.

Solution 2

You should keep in mind that loading the image data with the sample code you've provided in your own answer will block the main thread until the download has completed. This is a useability no-no. The users of your app will think your app is unresponsive. If you want to download an image, prefer NSURLConnection to download it asynchronously in its own thread.

Read the Apple documentation about async downloads with NSURLConnection.

When your download completes, you can then instantiate your UIImage from the data object:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    if (requestData)
    {
        self.image = [[[UIImage alloc] initWithData:requestData] autorelease];
    }
}

Where requestData and image are instance variables of your containing class, and image is a retained property. Be sure to release image in the dealloc routine of the class, e.g. using self.image=nil;.

Solution 3

It is true that Asynchronous loading is a must, but you can also achieve that with a background call if you just need a simple solution.

[self performSelectorInBackground:@selector(loadImage) withObject:nil];

- (void)loadImage
{
   NSURL * url = [NSURL URLWithString:@"http://.../....jpg"];
   NSData * data = [NSData dataWithContentsOfURL:url];
   UIImage * image = [UIImage imageWithData:data];
   if (image)
   {
       // Success use the image
       ...
   }
   else
   {
       // Failed (load an error image?)
       ...
   }
}   

Solution 4

You can load an image in a UIImageView from a URL without blocking the UI thread simply using the dispatch_async:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSURL *url = [NSURL URLWithString:myURL];
            NSData *data = [NSData dataWithContentsOfURL:url];
            UIImage* image = [[UIImage alloc]initWithData:data];

            dispatch_async(dispatch_get_main_queue(), ^{
                [myImageView setImage:image];
            });
        });

The first dispatch_async is used to load the image from the URL in background (without blocking the UI). The second dispatch_async is used to actually inject the image just loaded in the UIImageView. Please, note that the second dispatch_async is designed to work on the main thread (the UI thread) that is, indeed, the thread used to update the UI.

Solution 5

There is a really good example here using blocks: http://ios-blog.co.uk/iphone-development-tutorials/uiimage-from-url-%E2%80%93-simplified-using-blocks/

Share:
28,482
philfreo
Author by

philfreo

PhilFreo.com

Updated on June 04, 2020

Comments

  • philfreo
    philfreo almost 4 years

    How do you download an image and turn it into a UIImage?

  • philfreo
    philfreo over 14 years
    Excellent point. I was just looking at this also: markj.net/iphone-asynchronous-table-image
  • Andrew Zimmer
    Andrew Zimmer over 12 years
    This is an absolute must. Here are a couple of classes that handle asynchronous UIImage loading and caching using blocks. t.co/ovOn86KG
  • Rob Reuss
    Rob Reuss over 12 years
    Andrew - using your block-based approach, is the resulting UIImage being returned on a background thread? If so, I think that when assigning that to an UIImageView it would need to be explicitly done so on the main thread using performSelectorOnMainThread - yes?
  • Tony
    Tony over 11 years
    Take a look at the couple of libraries in my answer. I have been using it in a project and works great.