I'm looking into a fairly simple mechanism for caching and and currently using NSCache (for the reason of memory management). Question is - does the cache persist between launches? It seems like no to me.
I get objects put in cache just fine and can take them out of the cache while the app is running no problem. But once I relaunch, seems like the cache is gone.
So is there a way to make the cache persist between launches? If so, how would you re-sync the cache from previous session to the current?
NSCache does not persist between launches- if you'd like to save the cache, I'd recommend simply saving the data using CoreData- although if memory management is an issue, then perhaps you'd be saving too much. It truly depends on what you're developing.
Related
I’ve got a simple question
I made an application similar to instagram, the only difference is that it has more stories&posts because there’s no following system.
I do cache the images and videos, but should I delete the caches with a timer?
It is lots of videos and images.
Or is it enough to cache and when terminating the app clear the caches
If you're using standard caching mechanisms like NSCache, the OS will automatically clean it when it needs more memory for other applications. You don't need to worry about cleaning cache manually, unless you need some app specific behaviour.
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).
In my app I'm using RestKit v0.23.3 and I need to call 4 web service sequentially. I'm doing this without any problem following various tutorial that can be found on the web.
My problem is that I need to be sure to download all 4 services or data can be inconsistent.
Now my question: can I do a rollback on CoreData if one of the web services fails during the download/mapping operations ? Or is there a mode to disable the "auto save to persistent store" feature that RestKit has and save "manually" only when the last web service has ended ?
Thanks in advance for your help.
If this is really required then I'd be tempted to use a disk based solution - i.e. before you start any potentially destructive / corrupting operation you ensure everything is saved and make a copy of the data store on disk (note that multiple files may need to be saved so best to use API like
migratePersistentStore:toURL:options:withType:error:). Now, if you have a problem you can tear the Core Data stack down, restore from disk and then recreate the stack. This is safer and more reliable than trying to prevent saving or use an undo manager as the load process is run across multiple threads so you really need the saves to be running.
I'm developing an app with Core Data that periodically downloads all the data from a webservice. Since the download can fail or be cancelled by the user, I want to be able to roll back to the previous state. I tried undoing the NSManagedObjectContext, but that seemed a bit slow (I have tens of thousands of entities). What I'm doing right now is making a backup of the persistent store file, download the data, and, if the download fails, replace the store file with the backup. This seems to work correctly, except there seems to be a delay after I can fetch entities from the store: if after the download I go immediately to a UITableView that uses an NSFetchedResultsController, I find it empty. If I wait some seconds, everything is ok.
So my question is: has anyone had this kind of delays too? Is there something that can be done to avoid this problem, something that forces everything to be ready, even if it blocks the thread?
I haven't used this setup but I think the delay you are seeing is probably caused by Core Data having to clear all it's caching. Core Data uses If you use a cache with the fetched results controller it will have to test and then delete it's existing cache.
I think the best thing to do is to tear down you Core Data stack and reboot it from scratch. That includes recreating a fresh fetched results controller.