Andreas Storvik Strauman
Andreas Storvik Strauman

Reputation: 1655

Downloading UIImage in the "background"

Basicly I'm making an image gallery that downloads from the web.

So - when the user scrolls, a new image downloads.

Keep in mind that the code is very simplyfied, just to show you what I mean

-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
        // If new page then:
        [self loadNextPicture];
}

-(void)loadNextPicture
{
   NSString *url=@"http://www.example.com/image.png";
        NSURL *imageURL = [NSURL URLWithString:url];
        NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
        UIImage *nextImage = [UIImage imageWithData:imageData];
        myUIImageView.image=nextImage;

}

My problem is that every time a user scrolls to a new page, the application freezes for about a second while it downloads the image. Is there a way I can download it in the background so that the app won't freeze while downloading?

Appriciate every thoughts on this matter.

Andreas :)

Upvotes: 1

Views: 1278

Answers (4)

Mike Abdullah
Mike Abdullah

Reputation: 15003

Use NSURLConnection to load the data asynchronously.

Upvotes: 0

user42690
user42690

Reputation:

This little category will load the image in the background and show it once it's ready.

@interface UIImageView (BackgroundUrlImage)
- (void)loadURL:(NSURL *)url;
- (void)loadURLWithString:(NSString *)urlString;
- (void)backgroundLoadURL:(NSURL *)url;
- (void)backgroundLoadURLWithString:(NSString *)urlString;
@end

@implementation UIImageView (BackgroundUrlImage)
- (void)loadURL:(NSURL *)url
{
    NSError* error = nil;
    NSData *imageData = [[NSData alloc] initWithContentsOfURL:url options:0 error:&error];
    // TODO: check error!
    [imageData release];
    UIImage *image = [[UIImage alloc] initWithData:imageData];
    [self performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
    [image release];
}
- (void)loadURLWithString:(NSString*)urlString
{
    NSURL *url = [NSURL URLWithString:urlString];
    if (url != nil)
    {
        [self loadURL:url];
    }
}
- (void)backgroundLoadURL:(NSURL *)url
{
    [self performSelectorInBackground:@selector(loadURL:) withObject:url];
}
- (void)backgroundLoadURLWithString:(NSString *)urlString
{
    NSURL *url = [NSURL URLWithString:urlString];
    if (url != nil)
    {
        [self backgroundLoadURL:url];
    }
}
@end

In your example code you now can reduce loadNextPicture to:

- (void)loadNextPicture
{
     NSString *url=@"http://www.example.com/image.png";
     [myUIImageView backgroundLoadURLWithString:url];
}

Upvotes: 0

James
James

Reputation: 2376

You need to do it with an NSOperation so that it happens on a thread different from the UI thread. If you'd rather, you can use a library such as AllSeeingI (http://allseeing-i.com/ASIHTTPRequest/) or AFNetworking.

Upvotes: -1

esqew
esqew

Reputation: 44701

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

NSObject Class Reference

Upvotes: 2

Related Questions