Where are NSUserDefaults stored on El Capitan? - nsuserdefaults

In my Mac XCode project I have a bundle identifier of "com.gargoylesoft.DTS-macOS". I'm trying to blow away the stored defaults on this user so I did this:
find ~ -name 'com.gargoylesoft.D*' -exec rm -rf {} \;
When I then run the app, through Xcode, I'm still getting values from previous runs when I query NSUserDefauls. Where in the world is it storing this???

You must never delete (or edit) preference files directly on macOS! macOS caches preferences using a background daemon named cfprefsd. The daemon won't notice that you delete (or alter) the files, it keeps a cached copy in RAM that it will only expire if your system gets memory pressure. Memory pressure means: an app needs RAM but no unused RAM is available, then the system signals memory pressure, causing all kind of system services to flush their caches as that is still better than swapping to disk (will also work in your own application, just try to always use NSCache when caching data, as it will automatically react to memory pressure).
If you want to delete prefs, use defaults in terminal, like this
# defaults delete com.gargoylesoft.DTS-macOS
This will delete the file and it will make sure that also cfprefsd flushes its caches for that file.
Another advantage of defaults is that you also don't need to know if an application is sandboxed or not, as a normal application stores its prefs in
~/Library/Preferences
whereas a sandoxed one stores them in
~/Library/Containers/BUNDLE_ID/Data/Library/Preferences/
but defaultswill always look in the appropriate place.
Once you deleted a pref file by hand, you need to kill cfprefsd of your user (careful, there's one for your user and one for root - you don't want to kill the root one if these were user settings) and the system should then restart it for you. Or just reboot or at least log out and back in, both will restart it as well.

Related

On-demand resources - Force purge/clear of downloaded resource bundles

I have an swift4 app that is having certain issues where on-demand resources packages hang when downloading. The issue appears to be related to different versions of resource bundles being used in testflight environment as opposed to prod. Some users indicate that the packages do not download, but after several days (presumably after the bundles have been purged by the OS), the downloads start working again.
My question is, is there a way to forcibly clear the downloaded bundles rather than waiting for the operating system to remove them at its own leisure. I know it can be done via xcode (via purge in the data panel), but I need a solution that is native to the app itself.
(Using the NSBundleResourceRequest.endAccessingResources() function will only stop the resources being used, but will not remove them)
In short, there is no way to delete ODR programmatically. I asked a similar question on Apple Developer forums and got the answer:
There is currently no way to programmatically purge ODR resources. It is up to discretion the OS.
When a new network request for ODR content is initiated, the system will do a sort of inventory check, checking what is currently in memory and if there’s room for new memory. This check also takes into account several other metrics, such as which assets are currently being used, which were used recently, is the asset being used for the UI, etc.
After this is done, the system will determine how much of the chosen assets are to be purged, so that there is enough room to fit the new content. If I remember correctly, the OS will try and delete whole assetpacks. What this means is, if the system is purging assets, it will purge resources that are grouped together such as, all assets from Level 1, Level 2, and Level 3, provided the user is on Level 4. So, the system might purge slighly more space than exactly needed.
If you would like to change your app's ODR assets, you will have to submit an update to your app.

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.

iPhone app got rejected due to data storage issue

My app was rejected due to data storage problems.
After googling, I got these ideas. Please confirm my assumptions are correct or not.
Store the SQLite db in the caches folder and set the "donotbackup" flag, which will stop the file being deleted by the cache clean system.
But what will happen to the db if I update the app to a newer version? Any chance to loss the db?
Keep the cache files like images etc. in the Caches folder.
Do we need to clear the cache with our code or the device will clear it automatically?
Then I am storing all the data(including images) in the application's Sqlite db file. So should I implement iCloud in my application?
You must use "do not backup" attribute to files that you would to keep, other files place to cache folder.
Cache folder will be automatically erased when application terminates.
Check this article
Developers forum
Apple documentation

Managing iPhone app sandbox tmp directory size for caching images

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.

Iphone store image (pitfalls ?)

I have an application
that loads images from the net and stores it on the app's documents directory
so when the users starts up the application and doesn't have internet they still can use the application.
but my question is .. does the iphone controls that document directory ? does it clears itself after a certain period or after a certain amount of memory is used .. does the documents directory have a limit ? and what if the limit is reached ?
anyone can clear that up ?
In "Commonly used directories" section in application programming guide you can see that date can be stored in several directories: Documents, Library/Caches and tmp. Files in Documents and Caches directory persist between launches so you can store your data in either of them.
One more thing to consider is backup process - Documents directory is backed up by iTunes and Caches is not so storing large files or files that change a lot in Documents directory may significantly increase device synchronizing time (see "Backup and restore" section for details).
As answered here your application disc space is limited by 2GB, not sure what will happen if you hit that limit though.