Download images in the background to optimize downloads in ios

I am trying to optimize the loading in my application, in fact I have a lot of images uploaded to my application, and I spend a lot of time waiting for the view controller to open, especially the first initial view, which includes many images.

I looked at an apple sample

but I can’t recycle the whole application, I just want to tell me what should I do ?, am I implementing?

in tableview , where the cell is implemented by cellforrowatindexpath:

  NSURL *imageURL = ......; NSData *imageData = [NSData dataWithContentsOfURL:imageURL]; UIImage *imageLoad; imageLoad = [[UIImage alloc] initWithData:imageData]; imageView.image = imageLoad; 

Can i do something?

Thank you for your help!

enter image description here

+8
ios iphone uiimage uiimageview lazy-loading
source share
9 answers

Yes, you can add a placeholder to it.

It will not slow down scrolling and will load the image over time.

Also import this UIImageView + WebCache.m and MapKit Framework file

Here is the link to download the files.

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; } UIImageview* iV = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 50, 50)]; [iV setImageWithURL:[NSURL URLWithString:url] placeholderImage:[UIImage imageNamed:@"image_placeholder.gif"]]; [cell.contentView addSubview:iV]; [iV release]; } 

Just clean, create and run.

+3
source share

Try this code:

 dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); dispatch_async(q, ^{ /* Fetch the image from the server... */ NSData *data = [NSData dataWithContentsOfURL:url]; UIImage *img = [[UIImage alloc] initWithData:data]; dispatch_async(dispatch_get_main_queue(), ^{ /* This is the main thread again, where we set the tableView image to be what we just fetched. */ cell.imgview.image = img; }); }); 
+6
source share

Take a look at this control: https://github.com/nicklockwood/AsyncImageView

It is very easy to implement (only 1 header file) and is great for your needs.

Using this control: Instead of declaring:

 NSURL *imageURL = ......; NSData *imageData = [NSData dataWithContentsOfURL:imageURL]; UIImage *imageLoad; imageLoad = [[UIImage alloc] initWithData:imageData]; imageView.image = imageLoad; 

Using:

 NSURL *imageURL = ......; imageView.imageURL = imageURL; 
+2
source share

To enable the application when receiving images from the server and disable the block when downloading images, try using the UIImageView + AFNetworking library to asynchronously download the image from the AFNetworking server

  NSString *imageUrl = [[dict objectForKey:@"photo"] objectForKey:@"url"]; UIImageView *myImage = [[UIImageView alloc] init]; [myImage setImageWithURL:[NSURL URLWithString:imageUrl] placeholderImage:[UIImage imageNamed:@"PlaceHolder.png"]]; 

Just add this library and enable UIImageView + AFNetworking so you can use the new UIImageView imageWithUrl category

+2
source share

you can check this tutorial on NSOperationQueue , and it is on GCD exactly the same. You can also try:

 // Block variable to be assigned in block. __block NSData *imageData; dispatch_queue_t backgroundQueue = dispatch_queue_create("com.razeware.imagegrabber.bgqueue", NULL); // Dispatch a background thread for download dispatch_async(backgroundQueue, ^(void) { imageData = [NSData dataWithContentsOfURL:imageURL]; UIImage *imageLoad; imageLoad = [[UIImage alloc] initWithData:imageData]; // Update UI on main thread dispatch_async(dispatch_get_main_queue(), ^(void) { imageView.image = imageLoad; }); }); 
+2
source share

You can try something like that! ....

  dispatch_queue_t checkInQueueForPostImage = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); dispatch_async(checkInQueueForPostImage, ^{ UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:postAndCheckInDetails.postImageURL]]]; dispatch_sync(dispatch_get_main_queue(), ^{ if (image!=nil) { [uploadImage setImage:image]; } [cell setNeedsLayout]; }); }); 
0
source share

You can use async imageview.

 - (void) loadImageFromURL:(NSURL*)url placeholderImage:(UIImage*)placeholder cachingKey:(NSString*)key { self.imageURL = url; self.image = placeholder; NSData *cachedData = [FTWCache objectForKey:key]; if (cachedData) { self.imageURL = nil; self.image = [UIImage imageWithData:cachedData]; return; } dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); dispatch_async(queue, ^{ NSData *data = [NSData dataWithContentsOfURL:url]; UIImage *imageFromData = [UIImage imageWithData:data]; [FTWCache setObject:data forKey:key]; if (imageFromData) { if ([self.imageURL.absoluteString isEqualToString:url.absoluteString]) { dispatch_sync(dispatch_get_main_queue(), ^{ self.image = imageFromData; }); } else { // NSLog(@"urls are not the same, bailing out!"); } } self.imageURL = nil; }); } 

Check out this link . You will have the idea of ​​using async imageview.

0
source share

Here is a slightly modified approach to the answer to Ram Pasupolet. I added __block to make var img visible inside the block called in the main thread. Here is a complete definition of the method that I use in

 -(UITableViewCell*)cellforRowAtIndexPath:(UIIndexPath*)indexPath; 

for lazy thumbnail extraction. I also added placeholders for UIImageViews cells there.

 //lazy loading of thumbnails for images in cell via bg thread -(void)loadImageForCell:(CustomEditTableViewCell*)theCell withFilepath: (NSString*)filepath{ dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); dispatch_async(q, ^{ UIImage (__block *img) = [UIImage imageWithContentsOfFile:filepath]; UIImage *thumbnail = [[GlobalFunctions sharedGlobalFunctions] imageOfSize:CGSizeMake(40, 40) fromImage:img]; dispatch_async(dispatch_get_main_queue(), ^{ theCell.imageView.image = thumbnail; }); }); } 
0
source share

Use IDAsyncImageView.h

  ////////////////////////////////////// IDAsyncImageView.h ///////////////////////////////////// @interface IDAsyncImageView : NSObject @property (nonatomic, strong) NSCache *cache; + (instancetype)instance; - (void)loadImageView:(UIImageView*)imageView withURLString:(NSString *)urlString; @end ////////////////////////////////////// IDAsyncImageView.m ///////////////////////////////////// #import "IDAsyncImageView.h" @implementation IDAsyncImageView + (instancetype)instance { static IDAsyncImageView *_instance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [[self alloc] init]; }); return _instance; } - (instancetype)init { self = [super init]; if (self) { self.cache = [[NSCache alloc] init]; } return self; } - (void)loadImageView:(UIImageView*)imageView withURLString:(NSString *)urlString { UIActivityIndicatorView* activityView; activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; activityView.hidesWhenStopped = YES; activityView.center = CGPointMake(imageView.bounds.size.width / 2.0f, imageView.bounds.size.height / 2.0f); activityView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin; [imageView addSubview:activityView]; [activityView startAnimating]; UIImage* imageLoad = [self.cache objectForKey:urlString]; if (nil != imageLoad) { imageView.image = imageLoad; [activityView removeFromSuperview]; } else { // Block variable to be assigned in block. __block NSData *imageData; // Dispatch a background thread for download dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]]; UIImage* imageLoad = [[UIImage alloc] initWithData:imageData]; // Update UI on main thread dispatch_async(dispatch_get_main_queue(), ^(void) { [self.cache setObject:imageLoad forKey:urlString]; imageView.image = imageLoad; [activityView removeFromSuperview]; }); }); } } ////////////////////////////////////// ViewController.m ////////////////////////////////////// - (void)viewDidLoad { [super viewDidLoad]; [[IDAsyncImageView instance] loadImageView:myImageView withURLString:aUrl]; } 
0
source share

All Articles