Should I delete cache with a timer or? - ios

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.

Related

Clear Cache in iOS: Deleting Application Data of Other Apps

Recently, I have came across many apps which "Clear Cache" on iPhone. They also specify that you may lose some saved data and temp files.
What I know is that Apple doesn't allows you to access data of other Apps neither directory. So, how they are cleaning cache data? Can anyone put some light on it?
Reference: Magic Phone Cleaner
Power Clean
They simply fill the free space on iPhone temporarily with random data leaving the system with no free space at all.
This forces iOS to clear all temp data, caches and iCloud Photos -if you enabled storage optimization- to clear space. So basically they are tricking the system to force it to clear temp and cached data.
No app can access anything outside of it's sandbox environment. In other words, technically it's impossible to clean cache on an iPhone unless it's jailbroken. Most of these apps doesn't do what they say, they just give an illusion to user. Loading up the memory can force iOS to terminate other apps in the background but, I it's unlikely that it will give any performance boost.
It doesn't clear data in external apps, it clears external data left by apps. Clearing the cache basically deletes all the temporary files.

iOS - Best practice to save Images locally - NSCache vs Save in Document Directory

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).

SDWebImage not caching

I'm downloading images using [SDWebImageDownloader.sharedDownloader downloadImageWithURL] with options set to 0. I'm initially not doing anything with them, with the understanding that they will be cached. However, when I use the exact same function to later display an image, the function is downloading the image again, rather than getting it from the cache (the image cache type is 0). In both cases, the url of the image is the same. Is my understanding regarding caching incorrect?
The easiest way to enjoy cache functionality is to use SDWebImageManager instead of SDWebImageDownload. SDWebImageManager provides the SDImageCache functionality, whereas if you use SDWebImageDownload, you'll have to rely upon NSURLCache (which has limitations/issues) or write your own cache code.
Also (and implicit in Gustavo's question), if you're just trying to set the image of a UIImageView, it's actually even better to not use either of those classes, and use the UIImageView+WebCache category instead. It enjoys all of the cache abilities of SDWebImageManager, but also offers other advantages (esp for re-used UITableViewCell and UICollectionViewCell objects).
In a comment to another user, you say that you're downloading all of the images in advanced, "just to get them cached, so that when the user actually does want to see an image he doesn't have to wait."
That is a great stretch objective, but this sort of prefetch (sometimes call eager loading, in contrast to the more common lazy loading) has a couple of implications:
Unless you're confident that the user really will need all of the images, this is an aggressive use of their mobile device's cellular data plan, so maybe you should only do this if on WiFi (which can be determined by Reachability). Apple has even rejected apps for using too much cellular bandwidth.
The app will be more aggressive than necessary in terms of memory (causing more suspended apps to be terminated, which doesn't affect the UX for your app, but Apple asks us all to be good citizens and not use more RAM than we need). Again, if the user was going to need all of the images, then it's a fine thing to do, but if not, one should really minimize memory consumption, not loading the cache up with stuff that might not be needed for the current session. Also note that downloading a bunch of stuff that might need to be downloaded, but was done simply as a precaution has (modest) battery implications, too.
If you do a lot of requests for background data, make sure you're not using up all of the limited the network connections (you only have five) and backlogging the system with a lot of requests. The nice thing is that the UI UIImageView category naturally favors the current UI (being, fundamentally, a lazy-loading mechanism). But let's say there are 100 images, and the user fires the app and scrolls down to the bottom of the list. Do you really want the request for #90 (which is on screen and the user is waiting for) to wait for #1-89 to finish?
See WWDC 2012 video Asynchronous Design Patterns with Blocks, GCD, and XPC, section 7, "Separate control and data flow", about 48 min into the video for a discussion of how this is problematic.
If nothing else, I'd make sure that you test the app using the network link conditioner (part of the hardware IO tool for MacOS or under the Settings > General > Developer on the device). So turn on the network link conditioner, remove and reinstall the app (to empty the persistent storage cache), and then fire up the app with this slow connection, try navigating around while the image loading is in progress. A simple "let's kick off a prefetch of everything" may not offer the necessary prioritization of the current UI on a slow network that you really want.
All of this said, you may have thought through all of these implications, and if so, I apologize for belaboring the obvious. It's just that one has to be careful before implementing an aggressive pre-fetch of all images.

Does NSCache persist between launches?

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.

Pre-populate HTML5 offline appcache for a UIWebView in an iOS application

Is it possible to create a UIWebView that has an HTML5 offline appcache pre-populated so that it will work offline even if it is the first time the user is accessing the UIWebView?
If so, how?
I know I can achieve this through other mechanisms, but the above is my first choice. And I'm just plain curious if it's possible.
I'm seeing nothing about it in the documentation.
What you are looking for is two files in your cache folder.
ApplicationCache.db and cache.db
They both reside in Library/Caches/[your bundle identifier] folder for your application, which you have full access. You can add pre populated cache data to you bundle, and simply copy it to caches folder on you app launch.
BTW you can play with them easily, as they are simple, SQLITE db's.
I hope this helps
I think this may reduce to a question of whether you can programmatically write to the UIWebView's cache file (which is to say, whether the UIWebView cache resides within your app's sandbox) – if you can't, then game over. If you can, then it becomes a question of what happens after you drop a pre-populated cache file into place, and whether the UIWebView is "fooled" into thinking that it's already downloaded and cached your HTML5 content.
If you're using the iPhone Simulator to test your app, look in ~/Library/Application Support/iPhone Simulator/5.0/Applications (replace "5.0" with your iOS version, if necessary). You should see a long string of hex digits for each app you've compiled in the simulator; find the one that corresponds to your app, and then look in the Library/Caches/[your app's identifier] subfolder for a file named Cache.db.
This may be the place where UIWebView stores its cache data. If it isn't, game over and the answer to your question is "no, that's not possible". If it is where UIWebView caches data, then it may be possible to populate this Cache.db file in the simulator, grab the file, store it in your app bundle, and then write the cache to the appropriate location when it's time to pre-populate the cache.
At any rate, that's the line of attack I'd use to determine whether it's possible – I'm pretty confident the answer is going to be "no, not possible" unless it turns out the UIWebView cache does reside in your app's sandbox, is writable by you, and you can fool UIWebView by replacing its cache file.
What I mean by force loading is this: if a web page is visited, elements are cached for a faster load the next time. What I mean by force-loading or warming up the cache is to actually issue requests to the uiwebview in the background to load the data into the cache for faster loading so when the user actually clicks on it, it has the information in the cache.
If you use chrome, it's similar to their strategy they use to make surfing a little faster: when a page loads, they immediately find all links on the page and resolve the links so if a user clicks on the link, they don't have to wait for a response from the DNS servers before seeing the page as it's already done for them!
I hope this made a little more sense.
QUOTE:
this is a pretty cool question. consider looking at only what is provided in the developer reference as apple will reject your app otherwise. you can consider 'force-loading' whatever you want in a hidden view to warm up the cache. in this way, you have the ability to add elements to the cache but you don't have the power to remove items from the cache unless you know the internal caching algorithms... I'd say this is less of a hack and more of a technique! – vinnybad Nov 23 at 17:26
#vinnybad: I'm not entirely sure what you mean by "force-loading". Can you elaborate on that? (Sounds like it might be worth putting in an answer rather than a comment!) – Trott Nov 23 at 17:40

Resources