What happens if NSURLCache is full? - ios

I'm using default NSURLCache to cache images in my iPhone app.
What will happen if the cache is full and i'll try to cache another image?
Will it not cache the image? or it will be replaced with the oldest image cached?
Thanks alot

The maximum cache can be influenced with the initialization
initWithMemoryCapacity:... diskCapacity:... diskPath:..]
The new file will always be downloaded. (except when it's bigger than the maximum memory capacity, then it will just be downloaded and not saved in the cache)
If the maximum cache size is reached other file(s) will be removed.
It is not specified what files will be removed.
It's not difficult to create your own NSUrlCache and handle it yourself.
if you want to see a sample how to do that, then have a look at https://github.com/evermeer/EVURLCache

Related

What is the best way to Cache JSON request images for offline use?

I am new to networking and data caching in general. I am making a network request that returns me url strings which lead to images. I want to cache this data for offline use. What is the smartest way to do this using Apples frameworks(no third party libraries)?
Thank you!
If you do not want to use third-party libs you have only two options: write your own solution or use a NSURLCache
NSURLCache allows you to cache downloaded data in memory and on disk. The only issue with NSURLCache is that it does not guaranties everything you downloaded will be saved. For example it does not save (at least in iOS8) files that are bigger than 5% of the maximum disk usage. Also cache storage could be erased if device is out of the disk space. So NSURLCache usually is not suitable if you need a fully working offline solution. But it works great if you just need to reduce a network usage.
You could also read about NSURLCache here

Changing NSURLCache memory and disk capacity doesn't work

I'm using a NSURLSession configured to use the shared NSURLCache. I'm trying to change the size of the cache when the app goes in and out of background. The idea is to reduce both memory and disk capacity when the app enters background and restore the original capacity when the app enters foreground.
For both memoryCapacity and diskCapacity properties of NSURLCache the doc says :
At the time this call is made, the [in-memory|on-disk] cache will truncate its
contents to the size given, if necessary.
However, when I set these properties, the cache size never changes even if I set a value (much) lower than currentMemoryUsage or currentDiskUsage. Also I can easily verify that the memory used by the app doesn't change, an the size of the disk cache doesn't change either.
It seems that NSURLCache only use the values set when it is initialized and doesn't take into account subsequent changes. Calling the getters for memoryCapacity and diskCapacity does return my new values though.
Am I missing something or doing something wrong or is this a bug of NSURLCache ?
Probably an error in the documentation.

CALAyer vs CGLayer confusion: manipulating and saving images in the background

im pulling in images from the net, and want to manipulate them a bit such as adding perspective with CATransform3D, and compositing a couple together. After im done, I would like to save the file in memory so they can be pulled up when needed (like in a tableview cell for example). I managed to extract the image from the web, and manipulate them by making a CALayer. After a bit of reading, im a bit confused as to how to properly do this since these images arent displayed until needed and I obviously would like to do my work on a worker thread so the system wont lag. What would the best procedure be?
Apple recommends that you almost never try to cache images yourself since they cache them internally and you can be guaranteed that the cache will function properly even under high memory pressure.
You can cache an image using Apple's internal cache via the setName: and imageNamed: methods`. Furthermore, you should save a local copy of the image to disk in the caches directory so you dont need to download it again if the cache gets cleared.
So, in summary, use imageNamed:, if that is nil check the disk cache directory, if that is nil download the image. Caching a CALayer will make sooo much dirty memory,

In-Memory cache and DiskCache for Images Strategies

Now, I am developing a news reader app like BBC news iOS.
see in BBC News
In my app, I must download image from server to and show it in view to make users easier to choose the news they want to read.
For more performance, I must cache image to avoid reloading image for server.
I know that there are 2 kinds of cache: In-memory cache that saving images in memory (RAM) and DiskCach that save images in Disk to load it when we need.
My question is:
What is best images cache mixed strategies for my App? (use both in-memory cache and image-cache)
My solution is:
download image --> save them in diskcache + save them in memory cache --> load image from in-memory cache on demand and show in view ---> in-memory cache over its MAX_SIZE --> free in-memory cache ---> load image from disk cache on demand and save it to memory cache --> repeat........
Is my solution is right approach?
Another question: when in-memory cache over its MAX_SIZE --> we will free its --> all images in cache will lose so image in our view will disappear.
--> How to solve this problem?
Sorry for poor English.
Thank in advance.
In one of my projects I implemented pretty much the same caching methods (Disk Cache and Memory Cache).
Maximum cache size
Each cache system had its own max size limit. The "size" of each image was computed differently in the cache systems.
For the memory cache, each image would have a size computed as
image size = image width * image height (in pixels)
So, the maximum size for the memory cache would represent a the maximum area of a pixel surface
For the disk cache, I used the actual file size for each file.
Making room
When using the cache systems, you might get to a situation where one of the caches is full and you want to insert a new item in it - you have to remove some items to make room.
What I did was assign a timestamp to each entry in the cache. Every time I access that item I updated the timestamp. When you want to make room, you just need to start removing items from the oldest to the newest based on the last access timestamp.
This is a simple algorithm for freeing up space and in some cases might actually behave poorly. It is up to you to experiment and see if you need something more advanced than this.
For example, you could improve this method by adding a priority value for each item and keep old items in the cache if their priority is high.
Again, it depends on your app's needs.
Expiration
For the disk cache, I would definitely add an expiration date for each entry. If the memory cache is destroyed when the user completely terminates the app, images in the disk cache might be stuck in there forever.
Encapsulation
Another aspect I would consider, is making the caching system as transparent as possible to the programmer. If you want to enable/disable one of the cache it would be best to have most of the code remain the same.
In my app, I built a central content delivery system and I would always request images from the internet through this object. The caching system would then check the local caches (memory / disk) and either return me the image immediately or make a request to download it.
Either way... I, as the "user" of the caching system did not care what was happening behind the curtains. All I knew is I made a request to get an image from an URL and I got it (faster or slower depending if the image was cached).

When is disk cache cleared on iOS?

I'm using the cache to store a bunch of rendered thumbnails for my game. It can easily go up to 60MB if the user has all the content in the game.
I wonder if I need to clear this out myself? Does the OS do this for me, and if so when?
Thanks!
When I had an issue with the documents directory on IOS5 I found this article which discusses the cache amongst other subjects.
As I understand it; yes the OS handles the cache and it will clear it when disk space is low. What low actually means in size I do not know.

Resources