4

i have developed an app that can download mp3 files (nearly 6 to 8 mb of size) from online and stored in NSDocumentDirectory. my app get rejected today and says that

"Apps must follow the iOS Data Storage Guidelines or they will be rejected"


 We found that your app does not follow the iOS Data Storage Guidelines, which is
 required per the App Store Review Guidelines. The iOS Data Storage Guidelines 
 indicate that only content that the user creates using your app, e.g., documents,
 new files, edits, etc., may be stored in the /Documents directory - and backed up
 by iCloud. 

 Temporary files used by your app should only be stored in the /tmp directory; 
 please remember to delete the files stored in this location when the user exits 
 the app. "

i used to store the music files in NSDocumentDirectory . so, this is the first time am doing this, i cant figure out the actual problem. what should i do to resubmit my app for acception.

here is my code

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);



 NSString *documentsDirectoryPath = [[paths objectAtIndex:0]stringByAppendingPathComponent:[NSString stringWithFormat:@"psalmsMusic%d.mp3",i]];
NSLog(@"ddddddd psalmsMusic%d.mp3",i);
i++;


 NSLog(@"path %@",documentsDirectoryPath);
 [receivedData writeToFile:documentsDirectoryPath atomically:YES];

really need some help.

neerajPK
  • 293
  • 1
  • 4
  • 17

7 Answers7

7

i got my app rejected for the same reason , the solution is really simple instead of saving your downloaded files to the Documents directory you have to save them to the Cache directory which is a temp directory that don't get backed up to iCloud and can be randomly deleted by the OS on certain occasions ... this is how you save a file to the cache directory

NSString *filePath = [[self applicationCachesDirectory] stringByAppendingPathComponent:fileName];


BOOL flag = [[NSFileManager defaultManager] createFileAtPath:filePath contents: receivedData attributes:nil];

EDIT

NSString *filePath = [[self applicationCachesDirectory]  stringByAppendingPathComponent:[NSString stringWithFormat:@"psalmsMusic%d.mp3",i]];
NSLog(@"ddddddd psalmsMusic%d.mp3",i);
i++;
BOOL flag = [[NSFileManager defaultManager] createFileAtPath:filePath contents: receivedData attributes:nil];
if ( flag )
  NSLog("success");
ahmad
  • 1,212
  • 1
  • 14
  • 28
  • okay, can you please compare my code with yours. i still have some doubts about how to save the mp3 files in NSCachesDirectory – neerajPK Jul 12 '12 at 05:33
  • @neerajPK check the edit,,, all you have to do is to append the file name to the cachesDirectiory path ... and in the method createFileAtPath:contents: the 1st parameter the path you want to write to and the 2nd parameter is the NSData you want to write on that path – ahmad Jul 12 '12 at 06:08
  • okay, one doubt, how will i sync application cache data with my device. i mean how will i get the downloaded data? through itunes? – neerajPK Jul 12 '12 at 06:16
  • well this is kinda the point behind this . your data will not get synced through iTunes nor iCloud !! – ahmad Jul 12 '12 at 06:27
  • so, how will i play the downloaded mp3 file? – neerajPK Jul 12 '12 at 06:30
  • the same way you used to play them when they were in the Documents Directory , you just have to change the source path to be the same as the one you downloaded the file to ! – ahmad Jul 12 '12 at 06:32
  • resolution centre says that."Data that can be recreated but must persist for proper functioning of your app - or because customers expect it to be available for offline use - should be marked with the "do not back up" attribute. For NSURL objects, add the NSURLIsExcludedFromBackupKey attribute to prevent the corresponding file from being backed up. For CFURLRef objects, use the corresponding kCFURLIsExcludedFromBackupKey attribute. " so i think if i need to use the mp3 after downloading, i should say do not backup? – neerajPK Jul 12 '12 at 06:36
  • but when using cache , the recomented that delete all files when app exits ? so if i delete all files before exiting app, how will i get the mp3? – neerajPK Jul 12 '12 at 06:37
  • no , cache files will not get deleted when the app closes ! it only get deleted when the phone storage reaches a minimum limit... the files will stay there as long as the device has enough storage ! – ahmad Jul 12 '12 at 07:18
  • you have 2 options , either save them to the cache directory or mark them as do not backup ( but i dnt think this option is available for ios 5 ) , i choose to store my downloaded files in the cache directory and my app is working properly and i didn't get any complains from my users ! – ahmad Jul 12 '12 at 07:20
  • okay, will choose the first option. i think i can access the downloaded song from itunes as like NSDocumentDictionary did> – neerajPK Jul 12 '12 at 07:28
  • make sure it works on ios 4 and ios 5 and please dnt forget to accept the question if it was what you were looking for – ahmad Jul 12 '12 at 07:54
  • @ahmad, does NSCache works the same way as NSDocumentDirectory? – Bazinga Aug 29 '12 at 17:08
  • An NSCache object is a collection-like container, or cache, that stores key-value pairs, similar to the NSDictionary class. what you meant is NSCahcesDirectory, as far as i can tell they work the same ( coding wise ) but they differ in how the iOS treats each one of them – ahmad Aug 30 '12 at 04:55
3

Once the iCloud is implemented in Apple, The Document directory data is somehow related with iCloud Storage. Hence Apple is now rejecting the applications using heavy data storage in document directory.

You need to store the data at some other location. Store MP3 files At some other location.

This link May Help You.

http://www.techotopia.com/index.php/Working_with_Directories_on_iOS_4_%28iPhone%29

I Hope it'll Solve your problem.

Another is following..........

The iOS Data Storage Guidelines indicate that only content that the user creates using your app, e.g., documents, new files, edits, etc., may be stored in the /Documents directory - and backed up by iCloud.

Temporary files used by your app should only be stored in the /tmp directory; please remember to delete the files stored in this location when the user exits the app. Data that can be recreated but must persist for proper functioning of your app - or because customers expect it to be available for offline use - should be marked with the "do not back up" attribute. For NSURL objects, add the NSURLIsExcludedFromBackupKey attribute to prevent the corresponding file from being backed up. For CFURLRef objects, use the corresponding kCFURLIsExcludedFromBackupKey attribute.

See http://developer.appcelerator.com/question/134926/ipad-app-rejected-ios-data-storage-guidelines for details.

Jigar Pandya
  • 6,004
  • 2
  • 27
  • 45
3

Apple wants to reduce the size of your backup footprint.

First, stop using Documents. It's not appropriate.

If you are able to download the files again reasonably easy, you should store them in a place they won't be backed up. I suggest Caches. If they're purged, you should just download them again.

If it is difficult to download them again, you should store them somewhere else in the Library folder.

You can find the Caches directory using:

NSArray *paths = NSSearchPathForDirectoriesInDomains(
                        NSCachesDirectory, NSUserDomainMask, YES);

Basically, this is what you have now, but instead of NSDocumentDirectory you use NSCachesDirectory.

If you control the filenames, this is fine as is. If you don't, you should probably create a subdirectory and work from there so you don't collide with anything.

Steven Fisher
  • 44,462
  • 20
  • 138
  • 192
1

You can not store in NSDocumentDirectory because this directory is for syncing with iCloud now. But you can use NSCachesDirectory or use temp directory as apple comment states for store music file.

Ishu
  • 12,797
  • 5
  • 35
  • 51
1

the guidelines says that only important files that can't be recreated ( downloaded ) from the internet should go to the Documents Directory because this is t

ahmad
  • 1,212
  • 1
  • 14
  • 28
1

As per the iOS Storage Guidelines (which can be found at http://developer.apple.com/icloud/documentation/data-storage/) you should put all user-generated content in the Documents directory and all re-downloadable content in the Caches directory. So you should be fine putting the sqLite database there.

The background on this is that starting with iOS 5 the Documents directory is backed up to iCloud. As a lot of apps tend to store their complete data there the iCloud backups get rather large, which uses up the free space and creates network traffic, both of which in turn anger the user because he/she wonders why. To mitigate this Apple now seems to take a much closer look on what is saved into the Documents directory and if this is possibly regeneratable content (e.g. downloadable files).

Beware, that the Caches directory can and will be purged on iOS 5 by the operating system at times when the free space on the device gets low. Thus your app cannot longer just assume that everything is there as it was before but you rather have to re-check every time you access something out of your cache.

Hope this helps...!

sparta
  • 56
  • 2
0

my app also got rejected because of same reason - (2.3)

try this -

NSString *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);

The advantage of this whenever your device will Sync with cloud , at that time the application data will not synch because its in NSCachesDirectory instead of NSDocumentDirectory.

And Disadvantage is that whenever you will use your device and if you have less memory in your device. then CPU will might be clear cache for getting free space. so if you have any data for offline use, you might be loss.

2) If you can't use NSCachesDirectory (may be because your data is too important) then you can go with this way -

use this method and give your database path - 'addskipbackupattributetoitematurl'

go through this link - How to use addSkipBackupAttributeToItemAtURL API?

Community
  • 1
  • 1