3

I have a UITableView which contain several cell. When I click a cell, I push an other controller which shows the detail of this cell. In the detail I have a scrollView which contains several UIImageViews. I would like to download the images for these views from the web using ASIHTTPRequest, when the detail view is loaded.

Dan Ray
  • 21,623
  • 6
  • 63
  • 87
samir
  • 4,501
  • 6
  • 49
  • 76
  • 1
    possible duplicate of [How? UITableViewCell with UIImageView asynchronously loaded via ASINetworkQueue](http://stackoverflow.com/questions/3380791/how-uitableviewcell-with-uiimageview-asynchronously-loaded-via-asinetworkqueue) – JosephH Feb 28 '12 at 14:51

2 Answers2

4

You can override UIView. Each view has an ASIHTTPRequest. When each download has finished, you can use drawRect to draw the downloaded image.

this is a demo:

MyImageView.h

#import <UIKit/UIKit.h>

#import "ASIHTTPRequest.h"

@interface MyImageView : UIView <ASIHTTPRequestDelegate>
{
    ASIHTTPRequest *httpRequest;
    UIImage *image;
}

- (void)startRequest:(NSString *)_url;
@end

MyImageView.m

#import "MyImageView.h"

@implementation MyImageView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}


// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    [super drawRect:rect];
    // Drawing code
    if (image != nil) {
        [image drawInRect:self.bounds];
    }

}

- (void)dealloc
{
    [httpRequest clearDelegatesAndCancel];
    [httpRequest release];
    [image release];

    [super dealloc];
}


-(void)startRequest:(NSString *)_url
{
    if (httpRequest != nil) {
        [httpRequest clearDelegatesAndCancel];
        [httpRequest release];
    }

    httpRequest = [[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:_url]];
    [httpRequest setTimeOutSeconds:30];

    [httpRequest setDelegate:self];
    [httpRequest startAsynchronous];
}

- (void)requestFinished:(ASIHTTPRequest *)request
{
    if ([request responseStatusCode] == 200) {
        image = [[UIImage alloc] initWithData:[request responseData]];
        [self setNeedsDisplay];
    }
}

- (void)requestFailed:(ASIHTTPRequest *)request
{
    NSLog(@"request failed");
}

Usage:

MyImageView *imageView = [[MyImageView alloc] initWithFrame:CGRectMake(100, 100, 50, 50)];
[imageView startRequest:@"http://imageUrl"];
[self.view addSubview:imageView];
[imageView release];
xda1001
  • 2,449
  • 16
  • 18
  • How many images can this download at the same time? What is the iPad's threshold? Because I have a grid view of images (about 1000 max, but I load them 250 at a time). Will this work for me? – acecapades Oct 02 '12 at 01:48
1

Here's a class derived from UIImageView:

Header file, UIHTTPImageView.h:

#import "ASIHTTPRequest.h"

@interface UIHTTPImageView : UIImageView {
    ASIHTTPRequest *request;
}

- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder;

@end

and UIHTTPImageView.m:

#import "UIHTTPImageView.h"

@implementation UIHTTPImageView        

- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder {
    [request setDelegate:nil];
    [request cancel];
    [request release];

    request = [[ASIHTTPRequest requestWithURL:url] retain];
    [request setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];

    if (placeholder)
        self.image = placeholder;

    [request setDelegate:self];
    [request startAsynchronous];
}

- (void)dealloc {
    [request setDelegate:nil];
    [request cancel];
    [request release];
    [super dealloc];
}

- (void)requestFinished:(ASIHTTPRequest *)req
{

    if (request.responseStatusCode != 200)
        return;

    self.image = [UIImage imageWithData:request.responseData];
}

@end

Note that there's no reporting of errors, you may want an requestFailed: method if you want to report a problem to the user.

JosephH
  • 37,173
  • 19
  • 130
  • 154