dispatch_async for getting many images from url

864 Views Asked by At

I want to get many images from diffrent url and set it like image's buttons . I was trying to do this like it's showing above but nothing is happen . When i access this view controller it doesn't have any image for buttons and also neither the banner view is not showed... .

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){

            NSURL *url = [NSURL URLWithString: [pictureUrl objectAtIndex:i]];
            NSData *data = [[NSData alloc] initWithContentsOfURL:url];

            dispatch_async(dispatch_get_main_queue(), ^(void){

                UIImage *img1 = [[UIImage alloc]initWithData:data];
                img2.image = img1;
                [bt setBackgroundImage:img2.image forState:UIControlStateNormal];
  });
});
5

There are 5 best solutions below

0
On

Try this modification,

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){

       NSURL *url = [NSURL URLWithString: [pictureUrl objectAtIndex:i]];
       NSError *error;
       NSData *data = [NSData dataWithContentsOfURL:url options:0 error:&error];   
       if(error)
        {
           NSLog(@"Error: %@", [error localizedDescription]);
        }
        else
        {
          UIImage *img1 = [[UIImage alloc]initWithData:data];
          [bt setBackgroundImage:img1 forState:UIControlStateNormal];
        }
       // dispatch_async(dispatch_get_main_queue(), ^(void){
            //img2.image = img1;
       // });
});

Hope it help.

3
On

IMHO, you should use async and sync pairs, the inner block should be synchromous to the first one so it will take image when the data is downloaded and available. Also, don;t forget to handle errors:

Try like this:

// Show HUD here
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void)
{

      NSError* error;
      NSURL *url = [NSURL URLWithString: [pictureUrl objectAtIndex:i]];
      NSData *data = [[NSData alloc] initWithContentsOfURL:url options:0 error:&error];

      dispatch_sync(dispatch_get_main_queue(), ^(void){

        if(!error && data)
        {
            UIImage *img1 = [[UIImage alloc] initWithData:data];
            img2.image = img1;
            [bt setBackgroundImage:img2.image forState:UIControlStateNormal]; 
             /*
                //----OR----
               [bt setBackgroundImage:img1 forState:UIControlStateNormal]; 
              */           
        }
        else
        {
            // Do error handling here
        }
        // Hide HUD here
  });
});

Hope it helps!

0
On

Try this

dispatch_queue_t myQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
            dispatch_async(myQueue, ^{
                NSString *ImageURL = @"yourURL.jpg";
                NSData *imageData;
                if (ImageURL == nil || ImageURL == (id)[NSNull null] || [[NSString stringWithFormat:@"%@",ImageURL] length] == 0 || [[[NSString stringWithFormat:@"%@",ImageURL] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0)
                {
                }

                else
                {
                    imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURL]];

                }
                dispatch_async(dispatch_get_main_queue(), ^{

                    if (ImageURL == nil || ImageURL == (id)[NSNull null] || [[NSString stringWithFormat:@"%@",ImageURL] length] == 0 || [[[NSString stringWithFormat:@"%@",ImageURL] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0)
                    {
                        imageView.image=[UIImage imageNamed:@"photo_frame_noimage.png"];
                    }
                    else if (imageData == nil || imageData == (id)[NSNull null] || [[NSString stringWithFormat:@"%@",imageData] length] == 0 || [[[NSString stringWithFormat:@"%@",imageData] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0)
                    {
                        imageView.image=[UIImage imageNamed:@"photo_frame_noimage.png"];
                    }
                    else
                    {
                        imageView.image=[UIImage imageWithData:imageData];
                    }
                });

            });
0
On

I recommend you to use a library that supports cache for images. For instance, I used AFNetworking for one of my projects and it is awesome. And it automatically handles in background for you. In my case I needed a library that automatically cancels a request when I start new one and it worked for me. You can see the code here. And you can see similiar solution from another thread as follows:

AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest];
requestOperation.responseSerializer = [AFImageResponseSerializer serializer];
[requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"Response: %@", responseObject);
    _imageView.image = responseObject;

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Image error: %@", error);
}];
[requestOperation start];

Hope it helps you.

0
On
 imageView.image = [UIImage imageWithData:yourDefaultImgUrl];

   dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSData *imageData = [NSData dataWithContentsOfURL:yourImageUrl];      
        if (imageData){
            dispatch_async(dispatch_get_main_queue(), ^{               
                 imageView.image = [UIImage imageWithData:imageData];
            });
        }
    });

Hope it help.