iOS 5 does not allow to store downloaded data in Documents directory?

I have made an application for my client by keeping target iOS as 4.
But since the application still not submitted to Apple store, my client is planning to upgrade it for iOS 5.0.

For this I read the guideline from Apple and found that "Only user-generated data or that cannot otherwise be recreated by your application, should be stored in the /Documents directory and rest should be stored to /Library/Caches directory"

In my application, I am using server model of in-app purchase for non-consumable product. For this I am storing all my downloaded data (which are basically books or magazines) to Documents directory. The Database is also present in the same directory which contains the details about the downloaded products.

My question is,
1. Should I have to change my code to store the downloaded data to Library/Caches directory instead of to the Documents directory?
2. Where should my database file be placed (to Documents or Caches)?

If I put it products in the Caches then I have to change the logic of retrieval also, since it is considered that if record is present in database, there is no need change the existence of the file and it directly opens it when user clicks on the magazine.

Kindly guide me on this issue.
Thanks in advance.

UPDATED:
I am updating this for those who are still not sure about this problem.
Using the guideline of accepted answer, I have implemented this in 2 of my applications and submitted them to Apple Store. Both were approved in review.
This may promote that the solution suggested in the accepted answer is correct.


Here are the trade-offs:

  • If you put your files in the Documents directory then they are backed up to iTunes or iCloud but if they are too big and it's possible to download the files again then Apple may reject your app
  • If you put your files in the Cache directory then they won't be backed up and Apple won't reject your app. However, when iOS 5 gets low on space it may delete all the files in there.

However, with iOS 5.0.1 there is a third option:

  • Put files in Documents but flag them so that they are not backed up. There's a technote (QA1719) on how to do this.

I think this is probably the best answer for you.


1. Should I have to change my code to store the downloaded data to Library/Caches directory instead of to the Documents directory? = Yes, you need to store the downloaded data to Library/Caches directory.

2. Where should my database file be placed (to Documents or Caches)? = You can keep the database in Documents directory.


One app I know was once rejected because of this. Storing downloadable data in Documents dir is not recommended. The logic behind it is that your data should not unnecessarily inflate the app directory. This app directory is backed up in iCloud, so inflated app directory will cause more data to be saved in iCloud.

If data can be downloaded again, like magazines, books pdf etc. Then keep it in Caches directory. Of course you can store pointers to data (like URLs etc) in the Documents directory so that the user can retrieve them later.

To answer your questions:

  1. Yes, change your code to load DB from Documents and Data from Caches.
  2. Keep database in Documents

You'll have to add code to check if a document in DB exists in Caches, if it doesn't your app should download it again.


On top of the suggestion that you should keep the data in cache directory, there is a concern that you should keep in mind when keeping the data into cache folder:

Whenever iOS feels the memory crunch it deletes all the cache and temp folder. Problem is described here in detail To protect these directory not to delete and keep everything for lifetime you should use the attribute that will keep the mentioned directory safe. Solution is here:


I was looking for same query and I have got the solution . According to the apple data storage documentation dev may stored the data in cache even user want to persist that data in low memory situation.develper just need to set Do not back up flag.

Use the "do not back up" attribute for specifying files that should remain on device, 
even in low storage situations. Use this attribute with data that can be recreated but
needs to persist even in low storage situations for proper functioning of your app or 
because customers expect it to be available during offline use. 

This attribute works on marked files regardless of what directory they are in, including      the Documents directory. 
These files will not be purged and will not be included in the user's iCloud 
or iTunes backup. Because these files do use on-device storage space, your app is 
responsible for monitoring and purging these files periodically.

For more Information go through this link

Use Below Piece of code for setting the do not back up Flag.

import <sys/xattr.h>

- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
{
if (&NSURLIsExcludedFromBackupKey == nil) { // iOS <= 5.0.1
    const char* filePath = [[URL path] fileSystemRepresentation];

    const char* attrName = "com.apple.MobileBackup";
    u_int8_t attrValue = 1;

    int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
    return result == 0;
} else { // iOS >= 5.1
    NSError *error = nil;
    [URL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];
    return error == nil;
}

}

URL is the path of Data.