How to handle memory when many images has to be downloaded? - uitableview

I have created an app in which users will be able to upload the images and they can also see all the images uploaded by other users. I have integrated the code for the pagination and downloading the 10 images at a time and showing them on the UITableView. I have used AFNetworking for this task which is saving the image in the cache memory. The problem is that when user keeps downloading the images and count goes to around 300 images, app crashes because the device runs out of memory. I am looking for the best solution of this issue. What I have thought is to keep 50 images in the cache at a time and when user downloads the newer images, older ones will be deleted from the cache. Please also let me know if I can do this with AFNetworking.

You should use SDWebImage instead of downloading images it will cache and you can customise that caching option also .
Iam using this SDWebImage for caching 150 +images in UICollectionview and same in UITableview and its work perfect.
Initially we need to add a placeholder then it will appear one by one.
implementation
1.Take out the SDWebImage code
SDWebImage
2.Import the header file in to your viewcontroller
#import <SDWebImage/UIImageView+WebCache.h>
3.then add a single line of code inside cellforrowindex() method. i will gve you example code snaps
// Here we use the new provided setImageWithURL: method to load the web image
[cell.imageView setImageWithURL:[NSURL URLWithString:#"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];

Try APSmartStorage. You can manage number of images stored in memory. And if 'memory warning' occurred images will be removed from memory. But anyway it's ok because all images stored in files, so you don't need to reload them from network.

As #Aklesh Rathaur mentioned in comments, you could try SDWebImage, which is also used by Facebook on their mobile app.
It does a pretty good job at caching and freeing memory when more memory is required. Quoting How is SDWebImage better than X?
On the other side, SDWebImage caches the UIImage representation in memory and store the original compressed (but decoded) image file on disk. UIImage are stored as-is in memory using NSCache, so no copy is involved, and memory is freed as soon as your app or the system needs it.
Let us know your results :-)

Related

How to remove an image from Nuke for Swift cache

I have been trying out Nuke framework for Image caching, from https://github.com/kean/Nuke, across the document I couldn't figure out how to remove an image from cache (both disk and memory), I could find a method from Cache class "removeAll" to remove images from cache , but I have two questions:
How to remove single image?
How to remove all images from disk as well as memory cache?
I haven't tried anything I am trying to check the documents before trying , so down voting because I don't have attached code isn't fare.
To store unprocessed image data, Nuke uses a URLCache instance. So you have to call removeAllCachedResponses() of an appropriate URLCache instance.
As a result, you can clear image stored in disk as below codes if you use the shared instance of Nuke as mentioned by Sergey Di on the comment
Nuke.Cache.shared.removeAll()
Nuke.DataLoader.sharedUrlCache.removeAllCachedResponses()
If you use a custom shared ImagePipeline, it's a bit complicated but you can do like this code
(ImagePipeline.shared.configuration.dataLoader as? DataLoader)?.session.configuration.urlCache?.removeAllCachedResponses()
I hope my answer would help you.

Downloading images and display on table cell (Concurrent)

My app displays images in tableView cells What I want to achieve is to load the image in sequence even if the cell has disappeared off the screen. For example, I have cell 1 to 100, the cell is displayed and the images starts to download in background from 1 to 100 even if the user have already scrolled to cell 78. I'd also want to only download one to two image at a time so I don't bog up the network. With these criteria in mind, I was wondering what sort of setup would be most appropriate?
At the moment, I am using AlamoFire to download image. Would a combination of Alamofire with some sort of NSOperationQueue be suitable. I am very un familiar with NSOperationQueue at this stage. So I thought I'd try to find a recommended industry practice before I start going deep into setting NSOperationQueue
I'd also like to combine the functionality to continue the download even when the app is in background
Note. Any alternative library or framework solution is also welcome
The best solution out there is SDWebImage. The link to this repository is here.
If you wanna do it your own way without having any dependency then you have to follow the same things that SDWebImage does.
In short,
Asynchronously start download in thread, which downloads the images from the URL concurrently.
Then after downloading, use NSCache, to store the image and use the
imageURL as the key.
After storing the image in NSCache, also write the image in NSCacheDirectory, with the imagename same as that of its URL.
Now while fetching you have to check, whether the image exists in NSCache, using the imageURL as the key you can easily search that. If found, return image or then search NSCacheDirectory, whether the image exists there or not. If not then you must download the image and follow the steps once again.
Now NSCache is like the RAM. The data stored there will remain there as long as the Application is active. Once terminated, the data in NSCache will get cleaned.
Hence we also write the file in NSCacheDirectory, as data over here is persistent to as long as the app is not deleted from the device.
I hope I could make you understand as to how this thing works.
Cheers.

Managing the loading and unloading of 300 to 500 images in an iOS App

We are in the process of building an iOS app for creating a large digital catalog. On average the app will need to manage 300 to 500 images. These images graphically represent the item being offered and appear along side the description. The Android version of this app is complete and works as required.
The app requires 2 images for each item. A thumbnail for the list and a pic that is presented with the item description. The thumbnail is pre-processed to the needed size and presented with the list. It is not a separate pic created by the user and loaded.
Memory seems to be an issue as well, particularly with some of the early iPads that only came with 512 MB of RAM making the early models effectively useless unless we can find a better way to manage pics.
Currently when the app starts, the images are uploaded from a folder on a Windows server and temporarily held in cache. For the item list we have tried the load several above and several below approach but the speed is just not acceptable. We have attempted managing the size of the images, that helps but not significantly.
As I am new to this, I am attempting to find a more efficient way to manage the pics so the user does not experience the wait. I know that it has to exist.
Any assistance would be greatly appreciated!
Thank you in advance...
You can use third party library like SDWebImage to load image from URL.
You can write like this to load image from URL :
[myImageView sd_setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#",#"url"]] placeholderImage:[UIImage imageNamed:PROFILE_HOLDER_IMAGE]];
Now set below code in your view controller viewdidload() or viewwillAppear() Method.
[[SDImageCache sharedImageCache] setShouldDecompressImages:NO];
[[SDWebImageDownloader sharedDownloader] setShouldDecompressImages:NO];
i hope this will work for you.

AlamoFire image memory issue

I use alamofireimage for loading images async and I use AutoPurgingImageCache for caching the loaded images (url request). I have a pull-to-refresh feature in my app and after I do that even if the app content remains the same I see that the app size is increasing and alamofire does not fetch the images from cache and instead it loads them from new requests. Profiling the app reveals that a memory issue exists in alamofire. I have attached the screen shot. I would appreciate if someone has some insight into this.
What cache size did you specify? It's possible that you're experiencing cache misses because the number of distinct images you request per-refresh is more than large enough to fill up the entire cache.
It's also possible that the cache key, i.e. image URL, is changing between refreshes, which could prevent your caching mechanism from correctly looking up cached images.
It's certainly possible there's a problem with AlamoFire, but you should probably start by examining your caching setup for problems like the above.

Is there a big advantage to using SDWebImage over AFNetworking for image loading?

SDWebImage claims that AFNetworking doesn't cache the image itself but just the HTTP response, so SDWebImage is faster in recalling the image from cache and presenting it.
If I wanted to use purely AFNetworking, is such a claim, true or not, really something that is noticeable performance-wise? Is it something I should be wary of?
SDWebImage has much more control over image caching. It can cache to disk or memory.
AFNetworking relies on NSURLCache to persist images between app launches (and it's not very reliable), but it's great if you just need to cache during one run.
Both solutions cache a UIImage object in memory during the lifetime of the app. This is important because caching the NSData representation isn't fast enough to load images smoothly when scrolling through a table view.
Summary: AFNetworking's solution is simpler and will work for most use cases. If you need finer control, or disk caching, use SDWebImage instead of modifying AFNetworking's implementation.
It's not true.
If you look at the code, you can see that the category UIImageView+AFNetworking cache the UIImage (using NSCache and the urlRequest as the key). The cache isn't written to disk though.
I have used both :
SDWebImage is much much faster then UIImage + AFNetworking .
In UITableViewCell you can see the significant difference in performance . It was taking a hell lot of time in AFNetworking and the code is also too long . SDWebImage is much faster and short .
Use SDWebImage for better Image performance .

Resources