How to download multiple images asynchronously in iOS without effect on UI?

4 Solutions Collect From Internet About “How to download multiple images asynchronously in iOS without effect on UI?”

Use SDWebImage. You can download it from below url

https://github.com/rs/SDWebImage

For load 100 images using Asynchronous request

for(int i=0; i<99; i++)
{
    strImage=[[res valueForKey:@"result"] objectAtIndex:i];
    if ([[strImage lowercaseString] hasSuffix:@".jpg"] || [[strImage lowercaseString] hasSuffix:@".png"])
    {
        //[HUD show:YES];
        NSURL *url=[[NSURL alloc]initWithString:strImage];
        NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
        [NSURLConnection sendAsynchronousRequest:urlRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
        {
             thumbnail.image=[UIImage imageWithData:data];
        }];
    }
}

A sophisticated solution may become quite complex. Downloading and saving 100 URLs is not as easy as 100 times downloading one image.

The most vexing issue that will arise in ambitious but less smart implementations are memory pressures. A third party network library will not automagically solve this problem for you.

One simple – yet viable – approach which tries to avoid memory problems at the cost of a bit performance, is executing the download and save to disk operation all sequentially. This ensures, that only one image will be handled at any time. Thus, you can make safe assumptions about the maximum memory required for this approach.

A solution may look as below:

Suppose, you have an asynchronous method which loads the image data from a given URL:

typedef void (^load_completion_t)(NSData* data, NSError* error);
- (void) loadURL:(NSURL*)url completion:(load_completion_t)completionHandler;

This method will load the whole image data into memory. This isn’t really the best way, but IFF we can assume that one image always fits into memory, it becomes a simple solution.

Furthermore, suppose, there is a synchronous method which saves the data to disk:

- (void) saveData:(NSData*)data;

Now, given an array of URLs you can sequentially load and save a number of images as follows:

typedef void(^completion_t)(id result, NSError* error);

- (void) saveImagesWithURLs:(NSMutableArray*)urls 
         completion:(completion_t)completionHandler
{
    if ([urls count] > 0) {
        NSURL* url = [urls firstObject];
        [urls removeObjectAtIndex:0];
        [self loadURL:url completion:^(NSData* imageData, NSError*error){
            if (imageData) {
                [self saveData:imageData];
                [self saveImagesWithURLs:urls completion:completionHandler];
            } 
            else  {
               // handle error
            }
        }];
    }
    else {
        // finished
        if (completionHandler) {
            completionHandler(@"Images saved", nil);
        }
    }
}

The method above is an “asynchronous loop”:

The completion handler of loadURL:completion will call saveImagesWithURLs:completion:, much like a recursive invocation. However, this is NOT a recursive method: when the completion handler of method saveImagesWithURLs:completion:gets executed, saveImagesWithURLs:completion: already returned.

Given a propert which is an array of URLs:

@property (nonatomic, strong) NSArray* imageURLs;

you can invoke the asynchronous loop as shown below:

[self saveImagesWithURLs:[self.imageURLs mutableCopy] 
              completion:^(id result, NSError*error){
    if (error) {
        // handle error
    }
    else {
        // result equals @"Images saved"
    }
}];

You can call this method from the main thread. It will NOT block, because it is asynchronous. We also assume, that the completion handlers will be invoked on a private queue, and not on the main thread.

Better user AFNetworking, it will help you to download all the images asynchronously (no GUI hang)

https://github.com/AFNetworking/AFNetworking

You can use AFHTTPClient to enqueueBatchOperations and this has a completionBlock which is called when all operations are finished. Should be exactly what you’re looking for.