When does iPad clear library/caches? - ios

In response to Apple's changes in iOS data storage guidelines I recently reconfigured an iPad app to store its documents (50MB+) in the library/caches folder.
During testing in the iOS simulator I didn't see any problems with this cache when I simulated an update (following Brad Larsson's suggestion). I also tried deleting all of the contents of the library/caches folder to make sure that my app could recover.
However, when I released the app upgrade I found that my users complained of problems that were traced back to the iPad partially deleting this cache. It seemed like sub-folder structure was at least partially left intact, but sub-folder contents were deleted.
I've redesigned the app to deal with this situation during an upgrade, but I'm worried about what will happen when the iPad decides to clear the library/caches.
Does anyone have any experience or insight into the time when the iPad would try and delete items in this cache?
Thanks

There is no 100% clear answer to this question, because Apples iOS Data Storage Guidelines are very vague … They don't explain in which cases iOS 5 will delete data inside the cache dir …
In most cases iOS starts to kill files when it's getting low on disc space, but sometimes my app lost data for no good reason. So I had do implement some kind of recovery modus to redownload/-generate files the app needs.
This article is interesting: http://iphoneincubator.com/blog/data-management/local-file-storage-in-ios-5

The documentation states the following:
On iOS 5.0 and later, the system may delete the Caches directory on
rare occasions when the system is very low on disk space. This will
never occur while an app is running. However, you should be aware that
iTunes restore is not necessarily the only condition under which the
Caches directory can be erased.
The part about it never occuring while the app is running is crucial for our app, and is a really good insurance that we won't get unexpected behaviour.

Related

iOS iCloud documents: can I prevent documents from being purged?

I have an app that stores documents in iCloud. iOS seems to regularly purge the local copies of the ubiquitous documents, forcing my users to re-download from iCloud. I had assumed this was due to low storage on the devices but I’ve experienced it myself when my device has more than 3GB of free space.
I also see the same behaviour in the Apple Books app. On the other hand in the Apple TV app on the same device, purchased movies I download don’t ever seem to be automatically purged. This has been the case for me since around the launch of iOS 13, but some of my users have complained of the issue on earlier iOS versions.
Is there a flag I’m missing somewhere that would prevent iOS from purging my documents? The biggest these files get is around 5MB.
Edit based on following Warren Burton's link: After reading the document at https://developer.apple.com/icloud/documentation/data-storage/ , I'm wondering if what I'm looking for is the "do not back up" attribute. I'd previously interpreted this as meaning that if a user reinstalled from a backup, all my app's documents would be lost. But if documents are stored in iCloud, I suppose they would still be available in the same way after a backup is restored, so they don't actually need to be in the user's backup? To further add to my confusion, the docs at https://developer.apple.com/documentation/foundation/urlresourcekey/1408756-isexcludedfrombackupkey specifically say not to use this attribute on user documents, so maybe this isn't the right attribute. Can anyone clarify?
I’ve come to the conclusion that there’s no way to get the behaviour I want by just relying on the iCloud file management itself.
What I’m going to attempt to do is to copy files manually from the ubiquity container to the local documents and work with them there, saving back to the ubiquity container as necessary. It seems a bit inelegant but should get the experience I want.

iOS reducing size of binary in App Store update

I have an application that is currently in the App Store.
It has approximately 500mb of data that it needs in order to run.
I was fighting and fighting various methods to install this data after the app was downloaded, including AFNetworking and WhiteRaccoon, to no avail... the deadline was coming fast, so I decided to just ahem bundle the content into the App Bundle, and worry about it later. This meant the size of the app dictated that people downloaded it while on WiFi, but ... whatever.
Now, I have discovered NSURLSession, much to my delight, and it does everything that I need that I couldn't make the others do (see my answer to this question).
So... I am ready to push a new update to the App Store, and my Archive size has been reduced from 491.2mb to 32.2mb (!!?woohoo?!!).
I am curious how Apple manages this. I have read this document that mentions techniques that they use to keep the app bundle size down by detecting what hasn't changed, but it doesn't explicitly mention anything about the scenario that I am facing.
Now, if 460mb or so of obsolete bundle/code is going to be stored in the user's device, I'd like to be able to recommend to them that they delete the app entirely and reinstall... but I am curious if I/they need to do this, or does anyone know how Apple will handle this scenario ?
Thanks.
That document you reference, Technical Q&A QA1779: Reducing Download Size for iOS App Updates, covers what Apple does to optimize the size of the app update. But the net effect is the same as if the app bundle on the user's device was entirely replaced. As that document says:
In addition to new content, the update package contains instructions on how to transform the prior version of the app into the new version of the app. New files will be added, modified files will be replaced with their updated counterpart, and deleted files will be removed as part of this transformation. As far as the developer and user are concerned, this process is entirely transparent and the resulting updated app will be indistinguishable from a full download of the corresponding updated version of their app.
So, no, you don't have to tell users to delete the old app unless there's anything in persistent storage (Documents, NSUserDefaults, etc.), that need to be reset. And you should probably handle that programmatically, anyway.

iOS deleting all app sandbox data automatically

I have a very strange issue that has been occurring to a few users of my app. One of the users actually described the issue to me.
My app downloads magazine data to the device to allow for offline reading. This means that users can sometimes have around 10 gigs+ downloaded to the device.
The problem this user experienced (and a few others have too) is that randomly all sandbox data gets deleted from the app (included core data files). The user told me that he was downloading something in a different app and got the "Storage Almost Full - You can manage your storage in Settings" popup message.
He went to the settings app and went to General > Usage. He then saw the app was using around 13 gigs of data. While he was in that list he said every time he went out of the Usage tab, then back in the app's data was getting smaller and smaller. Until eventually the app said it was using 0mb.
When he logged back into the app all his data was deleted and core data was also removed which lead the app to think he was a completely new user with no data downloaded.
I then ran some tests on my own where I made sure my device only had 100mb of space available. I then started downloading in the app. The warning message popped up alerting me I was running out of space and I ignored it and continued downloading. I have now downloaded about 1.5 gigs of data and am still downloading and the device seems like it is freeing up space somewhere else to make room for my downloads.
I've searched far and wide and have found no one else ever experiencing a problem like this. So my questions are:
Has anyone else every experienced this issue before?
Does Apple have a policy that will remove app data from the app that uses the most space if the device is running out of space?
Is there an algorythm that decides which app will get cleared when space is running out?
Is there a way to tell the OS not to remove data when running out of space?
Any help would be appreciated!
Assuming you're storing the data in the caches subdirectory:
On iOS 5.0 and later, the system may delete the Caches directory on
rare occasions when the system is very low on disk space. This will
never occur while an app is running. However, you should be aware that
iTunes restore is not necessarily the only condition under which the
Caches directory can be erased.
Documentation here

Potential App rejection possibility on the Apple App store

Today while investigating how/where to download and save audio/image files from a URL in a project I am working on, I stumbled upon a potential app rejection possibility if we save large audio/image files in the documents directory in iOS.
The issue here is related to 'iOS Data Storage Guidelines' published over here https://developer.apple.com/icloud/documentation/data-storage/
- "Only documents and other data that is user-generated, or that cannot otherwise be recreated by your application should be stored in the '/Documents' Directory and will be automatically backed up by iCloud."
On further reading, I found that many people had their apps rejected because of storing too much data in the documents directory (since a user has a limited amount of 5GB in his iCloud account) and the documents directory for all apps on a users device is automatically backed up to iCloud.
An option given to developers is to store data in the '/Library/Caches' directory. However data present in caches directory can be deleted anytime the OS is low on memory and there is no guarantee that the data will be present always which is not an acceptable solution to our project since we cannot expect our app's user base to download large files more than once.
The solution which I found according to this link http://developer.apple.com/library/ios/#qa/qa1719/_index.html#//apple_ref/doc/uid/DTS40011342 is to specifically mark the files you store in Documents directory for not being backed up and the process is described therein.
However, it is only applicable from iOS 5.0.1 onwards. It is not possible to exclude data from backups on iOS 5.0 and below.
So, my question over here is:
'Since the project I am working on has a sufficiently large number of images/audio to be stored and re-downloading them is not an option , would it be advisable to support installations only on iOS 5.0.1 and above because of the above mentioned issue or keep backward compatibility with iOS 4.3 and investigate other ways to store the data without the app being rejected? Approximately what percentage of users do we stand to lose if we go with the former approach? Are there any statistics for the same?'
Please let me know your thoughts on this
Several things:
iOS 5 is more than 80%, possibly more than 90%. (The site I watch has had a surge in iOS 4 % recently, but I believe that's being caused by not counting iOS 6 devices.)
You should explain the nature of your data a bit more. If your data is difficult enough to download, it may qualify for backing up anyway. (This happened to my app.)
The users who are still running iOS 4 are less likely to download your app anyway, unless you have an existing iOS 4 installed base.
iOS 4 support is going to cause you more and more pain and suffering.
References:
http://www.game4mob.com/index.php/tech-articles/67-ios-5-penetration-percentage
http://tewha.net/2012/06/dont-write-new-apps-that-target-ios-4/
Prior to iOS 5 the /Library/Caches directory isn't cleared by iOS. The Do Not Backup feature was added to iOS 5.0.1 because the new cache clearing in 5.0 broke a lot of apps, such as instapaper - see Marco Arment's blog post on this issue: http://www.marco.org/2011/10/13/ios5-caches-cleaning
Maybe you can use /Library/Caches for those users below ios 5.0.1 and move over to using the Do Not Backup marker after they upgrade.

Questions concerning iCloud + core data

I have an app on the app store, that uses coredata as storage. I wan't to update the app with iCloud synchronization as new feature. Following apple`s sample code, I managed to have my core data storage synchronize between devices.
However, I'm experiencing problems when either iCloud synchronization is turned off/on in the app on only one of the devices, or when the app is deleted from the device and the reinstalled. In both cases, data is not synchronized back to the device, although it is available just fine on a second device (which was not disabled/reinstalled).
I also found that all storage is effectively erased completely, when I delete the app from all devices, and then reinstall. Althrough I get a couple of merge notifications in the console (even some without errors), I can't see no data in the local storage of the device.
Browsing the mobile documents folders on my mac still reveals lots of transaction logs in the icloud storage of my app.
Even deleting the app from all devices and starting from scratch wont sort things out. I will end up in a situation where data is either only synced to one device, or not synced at all.
I wonder if there is anything I can do about this inconsistent state that is created when only one device is temporarily iCloud disabled, or the app is deleted from ONE device?
As for my code, its an 1:1 copy of the recipces example from apple.
Daniel Pasco talked about using Core Data and iCloud together at NSConference 2012. Some notes from that blog post:
launching with -com.apple.coredata.ubiquity.logLevel 3 to get a spamfest in the message log saying what Core Data and iCloud are doing.
The conclusion from this talk appears to be that using Core Data and iCloud are really not ready for each other at this stage.
He posted an updated Core Data Recipes project on Github which may or may not fix your problem.
Apple makes it seem easy, but there are a number of nuances with regard to correctly seeding iCloud with data, and what happens afterwards when iCloud support is toggled on and off on different devices.
I implemented a sample project that demonstrates a straightforward way to add iCloud support to Library-style CoreData apps. It's called iCloudStoreManager and it's available on github.
I'm still testing it before I add iCloud support to one of my own production apps. It's working, but I see unexpected errors and delays when an iPad 3 is in the mix. It works, but with long delays.
I've also tested with iPhone 4, iPhone 4S, and the original iPad, and any mix of those devices works well in my experience.

Resources