I want to be able control how much time the image is stored in the cache. This is how i download the image using afnetwork:
[myImageView setImageWithURL:url placeholderImage:placeHolder];
I looked it up in the documentation, i didn't find anything interesting.
any clue?
EDIT: Additional question: is the cache stored in the disk? i guess so because images remain in the cache even after i close the application. but i am not sure.
AFNetworking uses an NSCache instance, which will store more and more images in memory, until a memory warning is received, at which point it will remove some or all of the messages. NSCache does not save to disk.
AFNetworking also uses NSURLCache, which caches URL responses to disk based on (1) your NSURLRequest settings and (2) the cache headers sent by the HTTP server. You can adjust the caching behavior in your app by setting the NSURLRequestCachePolicy, and on your server by setting the cache headers.
If that doesn't give you enough control, you may want to check out SDURLCache, an open source NSURLCache alternative.
Related
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.
I am fetching images from my server and need to store them on the disk. I was wondering what is the best way to cache these images to prevent excessive requests and traffic. From doing some research it seems that there are many options available but I am not sure which to use.
Core Data
Store in the Cache Resources Folder in the file directory
After storing these is it best to use a NSCache class to put these data into memory for quick access or is Core Data quick enough?
Based on my experience, you could use SDWebImage, which caches the images you request based on their url, so the next time you "request" it, it will check if it is in cache, if so it won't make the request and it will load it from it instead.
I'm not sure why would you need to store the image, maybe you could tell us the reason and see if we can help any further.
I've had great results using FastImageCache by Path.
What Fast Image Cache Does
Stores images of similar sizes and styles together
Persists image data to disk
Returns images to the user significantly faster than traditional methods
Automatically manages cache expiry based on recency of usage
Utilizes a model-based approach for storing and retrieving images
Allows images to be processed on a per-model basis before being stored into the cache
I'm developing an app that similar to Instagram feed (tableviews with cells that contain images and some labels).
For all the data I'm getting from the database, I'm using Data Task (because it doesn't take much to receive them), but for the images (which their url's I get with the Data request), I need to save locally for future use (improve user experience).
My logic is the following:
Save in NSCache or in Document Directory, the images inside folder with the date they been downloaded(create it once and append all other images if needed) (I'm deleting every folder which is not from the recent 7 days), and then for the TableView, just load if from there, so the tableview will scroll smoothly and won't load the url directly from its delegate method.
So where is the better place to store them according to my needs, NSCache or Document Directory.
Looking forward to hearing your suggestions, Thank you!
NSCache and persistent storage serve largely different purposes. NSCache holds the item in memory and is used for optimal performance. But it takes up memory (RAM) and you really should make sure that if you use NSCache that you respond to memory warnings and purge the NSCache in those cases. And when the app terminates, the NSCache is lost.
Using persistent storage cache (generally the Caches folder) is used for a different purpose, saving you from needing to re-retrieve the asset via some network request, but not holding the resource in memory. This makes it a great cache mechanism across sessions of running the app or in situations where you may have encountered memory pressure, purged the NSCache, but didn't want to re-retrieve the asset from the network.
Note that I mention the Caches folder for persistent storage, whereas you seemed to presume that one would use Documents folder, but there are two considerations:
Apple is getting more particular about apps only using Documents folder for user data that cannot be easily recreated, and using Caches folder for data that is easily re-retrieved. See File System Basics for more information.
Starting with iOS 11, you should only store user visible documents in the Documents folder (see WWDC 2017 Fall video, iOS Storage Best Practices). Even if you had internally used files that were not easily reconstructed, unless the intent was to eventually expose the user to them, you'd use the Application Support directory, not the Documents folder.
Bottom line, one would generally use the Caches folder for a persistent storage based cache.
Note, we'll often use a two-tier cache mechanism. Cache the resource to both NSCache and the Caches folder. Then, when you go to retrieve a resource, first check NSCache (really fast), if not there, check persistent storage, and if not there, re-retrieve the asset from the network.
Having said all of that, to make it even more complicated, there is a third type of cache, that provided by NSURLCache (i.e. responses for network requests are transparently cached by NSURLSession and NSURLConnection). This cache is dictated by poorly documented rules (e.g. it won't cache any single item whose size exceeds 5% of the total cache size) and is subject to the HTTP headers provided by the network response. This cache, though, operates largely transparently to you and provides both memory and persistent storage caches. Often you can enjoy NSURLCache caching behavior with absolutely no intervention on your part. It's seamless (when it works).
Trying to debug my app, but my memory keeps increasing .
I have an app that pulls JSON from a web service with AFNetworking. I use UIKit + AFNetworking to load the URL string that I got from the JSON in UIImageView which are in a custom XIB table cell. I use setImageForURL.
When I load new JSON and hence new image URL's, my memory usage jumps by 2-7 mb each time. The old images are replaced in the UI by new ones. Live memory usage goes up and up. I've looked into the arrays holding the JSON and so forth - no leaks.
I suspect there is some image caching going on but I've never seen any information regarding image caching when using UIImageView with setImageWithURL. I've seen memory issues using imageNamed though.
Does setImageWithURL have the same memory issues as imageNamed?
setImageWithURL: from AFNetworking handles the caching of the images downloaded with this method. The next time you call this for the same URL it will check the cache first to see if the image is cached (so no need to go network again).
From AFNetworking API:
Asynchronously downloads an image from the specified URL, and sets it
once the request is finished. Any previous image request for the
receiver will be cancelled. If the image is cached locally, the
image is set immediately, otherwise the specified placeholder image
will be set immediately, and then the remote image will be set once
the request is finished. By default, URL requests have a Accept
header field value of "image / *", a cache policy of
NSURLCacheStorageAllowed and a timeout interval of 30 seconds, and
are set not handle cookies. To configure URL requests differently, use
setImageWithURLRequest:placeholderImage:success:failure:
So there is indeed caching, hence memory usage.
Hope it helps.
I read something about multi thread access on DB but still not sure best way to do that for reading/writing in conjunction with async network download.
For instance I will have a page with images from the web, so I'm retrieving them by their URLs, using AFNetworking but I want to check first on my DB and write on it (or disk) the retrieved image for future use.
What can be the best way to do that without blocking the UI (like when scrolling)?
If I do that with a singleton that reads/writes it block the main thread.
Thanks for any tips on that.
AFNetworking is not the tool for that. Instead, you can take advantage of the built-in functionality of NSURLCache--specifically Peter Steinberger's fork of SDURLCache.
In -applicationDidFinishLaunchingWithOptions:, do NSURLCache +setSharedCache: with an instance of SDURLCache (with some amount of disk space allocated). All requests made through UIWebView (and AFNetworking, for that matter) will automatically be routed through NSURLCache before the request is made to check the cache. It's unobtrusive, drop-in, and follows cache directives correctly, and it should solve your problem quite nicely.