Managing iPhone app sandbox tmp directory size for caching images - iphone

I have a fairly image-intensive iPhone app, and I'm looking to store remotely downloaded images locally in the app's sandbox tmp directory to avoid unnecessary network requests. Is there a limit to the total size of the files stored in an app's directories, or does the app need to manage that? How would the app determine the size of the files in the tmp directory?
Also, if the app needs to manage the size of the cache, I'd like to implement some kind of cache policy to determine which files get invalidated. How would I go about doing this? If I want to implement a basic LRU caching policy - invalidating files that have been used least recently - it seems like I would need to store access counts for each image and store that on the disk as well, which seems kind of funky. I suppose an easy size management policy would be to simply completely wipe the cache each time the application terminates.
Also, what's the difference between using the directory from NSCachesDirectory versus NSTemporaryDirectory? The Apple docs mention both, but don't talk about which one to use for what type of files. I'm thinking the NSTemporaryDirectory is more like a Unix /var/tmp directory, and used for ephemeral data that can be wiped out at anytime. Seems to me the NSCachesDirectory is more appropriate for storing cached images, since the files could be needed across multiple app lifecycles.

All temporary directories are local to your application; any of them will work and there is no artificial limit to the size of their contents.
A persistent LRU cache policy should be both sufficient and relatively easy to implement.

Related

How to make iOS app cache ALL request responses?

I'm starting to work on an app which will include in quite a few places data that I will download from my server each time user is asking to view them. Then, when user opens app again without any internet connection, app should let him view any content it previously downloaded, just loading it from the cache. The point of this is that the content changes from time to time and user needs to be able to see the last downloaded version if he can't connect to the server.
Problem is, I can set the cache to a certain size on disk, but I have to store ALL the content no matter the size. I suppose I'd have to set cache disk size to make it bigger when it's running out of space. What is a good way to do this?
P.S. Not sure if this is relevant, but I was thinking about trying AFNetworking for this project (previously I used ASIHTTPRequest).
If you're using NSURLCache as an on-disk cache, you can check the disk usage with currentDiskUsage. If this is approaching diskCapacity, you can increase it using setDiskCapacity. You should perform this check before you attempt to write to the cache.
I have worked on same type of project, I used AFNetworking and according to me storing the data in local database is better option then caching it... and at the time when user starts app just have one service call which just checks the database version. If its old version replace database and handle the case if network fails by displaying the older version.

Apple "Avoid writing cache files to disk." - where should I save cache?

In Apple's Performance Tuning Guide there is a writing:
Avoid writing cache files to disk. The only exception to this rule is
when your app quits and you need to write state information that can
be used to put your app back into the same state when it is next
launched.
I'm saving a lot of cache files in Library/Cache directory, because my app deals with web services, and nobody likes the white screen. What does this statement mean? I shouldn't do this or what?
Thank you!
Well, "avoid" means "avoid if possible, because writing/reading is relatively slow". If by caching a small amount of data (I assume the definitions of the web services retrieved from somewhere?) you can improve the performance of your app's startup, by all means do it. If you are only using this data for one run of your application, and the next run will re-fetch this anyway, use an in-memory cache.
Library\Caches is basically designed to store data you fetched from somewhere which provides performance boosts when stored locally.
The text from Apple feels like more a general guideline against overusing storage if you don't need data to persist from one run of your application to another.

Strategy to cache / persist downloaded images in iPhone App

My app needs to download about 50 images from an online MySQL database which I'm maintaining. I know I can control the way they're cached using (for example):
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:aURL]
cachePolicy:NSURLRequestReturnCacheDataElseLoad
timeoutInterval:30.0];
But:
1) does using this caching-policy mean the images will truly forever remain on the user's device after they've been downloaded the first time? OR,
2) am I better off manually saving them myself to the app's Documents folder (perhaps also concurrently writing a database to there to mirror the one online) to ensure their persistence - that way I can just load them from there (the device's Documents folder) from that point on, on all subsequent runs of the app?
Basically just need recommendation on the best way to persist the images on a user's device after their initial download - so the user always has something to look at in case connectivity issues are preventing them from being able to grab whatever new images have been added to the online database.
Any and all advice would be highly appreciated.
NSURLCache uses a memory and a disk cache for downloaded requests. I remember there being issues pre-iOS 5 which led to separate libraries like SDURLCache, but I don't think they're needed anymore.
Even with the disk cache, it may still be cleared out by iOS when space on the device runs short. If you don't want this to happen, you can store the images yourself in the Documents folder... but this situation is what the Caches directory is meant to be for. You download the images, they hang around unless the device runs out of space, in which case they're cleared and re-downloaded as needed. If I was a user of the app, I would prefer that behaviour over permanently taking up disk space for things that can easily be restored from the network.

Better way of updating images bundled with the app

In our iOS app we have close to a hundred image files in resources bundle. Now we want to make them network based since the images may change (updated/no longer needed/additions) at any time. We are debating at what approach would be optimal. From what I have read, I understand that the resource bundle will not be editable on the device. So, when I start the app, I will check from the server if there are any image updates. If so, I will download the changed images and then save them to documents directory. Then in the app, for every image, I will basically have to check if it is in the resources bundle, then grab it from there. Else pick it from documents directory and display it.
Another approach is I don't have anything in the resources folder, I download all images on app launch from the server and store them to documents directory and then on, download the changed files at subsequent app launch. Here I am eliminating the check on resources folder if an image is present or not and my app bundle size would be reduced.
The third approach would be to copy the files from my resources directory to the documents directory on first launch and thereafter continue from documents directory.
Any suggestions on what would be a better approach or all of them would be similar from the performance point of view?
IMO, option three offers the best balance between eliminating needless code and preloading as much data as possible. You don't want to make the user wait for 100 image downloads when the app starts the first time, so pre-load as many as possible. The copy code is simple and will only be used once. So that eliminates the runtime checks you'd have to do with the other options.
No worries, performance will not be an issue, unless you use a particularly unwise image lookup algorithm.
Filesystem traversal should be pretty fast for such a small amount of files.
Before implementing something yourself, I would recommend looking at something off the shelf for Image Caching. Namely EGOImageView from EnormEgo.
I have used it in several applications which are dependent on grabbing images from URLs. It handles everything for you, you just set up a 'background' image for it to show while it goes about it's business of grabbing the URL based image in the background. The second time you use it, it's available immediately. Definitely gets my vote for ease of use...
p.s. it's free to use

how to decrease the application size

My problem is that my application size is very high,
is there any idea to reduce size of application?
if i make application without content and content is uploaded my server then how i sync the application with content put on my server?
i want to know that once user download application after that when he use application then we stream the content and save his document folder.
once user stream then never required for streaming.
is it possible????
Thanks,
Reducing the size of your application depends on the TYPE of contents of your application. I highly doubt that the application code is the cause, and since you did not mention what they are I am assuming they are some kind of resource.
If your resources are images, try to use image compression programs. Or convert them to smaller sized images or optimize the images.
If your resources are documents / text files / files that have a high compression ratio when zipped. Then you can try to zip your resources and access them inside the compressed file (this will mean additional coding, and probably slower in performance).
These are just examples.
It is not advisable to stream large contents because it uses the network bandwidth which, depending on the user's plan, can cause a big spike in phone bills.
Yes it is possible that you can download your content and can save to application's document folder, when user runs your application for the first time. Thought it may affect the first impression to your user as it will take time to download.