Any other ways to access Documents Directory on iDevice Locked State? - ios

I am implementing Music Player application in iOS platform. Here I am storing and retrieving the media contents using Documents directory. So I can't able to access the 'Documents Directory' when iPhone is getting locked with passcode. I referred Apple developer library, they said the Encryption & Decryption is comes under the accessing the file contents from documents directory. So if device is getting locked the Decryption key is Destroyed. Here I have attached the Screen shot of Problem Description. I was stuck with this problem last 2 months. Pls give me any other ways to access the Documents directory at locked state. Not Only Media , Any other content*.
Thanks in Advance.
Apple Developer Site:
https://developer.apple.com/library/mac/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html

You need to specify the file protection level as an option when you write your files. Example:
[someData writeToFile:filePath options:NSDataWritingFileProtectionNone error:&error];
In this, someData is an NSData representation of the data you want to write to disk, filePath is the string path where you want to save the file.
Read the documentation on NSDataWritingOptions in the NSData Class Reference for more encryption options.

Related

My app got rejected due to not following iOS App Data Storage Guidelines

My app got rejected due to not follow iOS App Data Storage Guidelines.
My binary was rejected by the Apple App Store Review Team.
On launch and content download, your app stores 6.34MB on the user's iCloud, which does not comply with the iOS Data Storage Guidelines.
Next Steps
Please verify that only the content that the user creates using your app, e.g., documents, new files, edits, etc. is backed up by iCloud as required by the iOS Data Storage Guidelines. Also, check that any temporary files used by your app are only stored in the /tmp directory; please remember to remove or delete the files stored in this location when it is determined they are no longer needed.
Data that can be recreated but must persist for proper functioning of your app - or because users 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 kCRUFLIsExcludedFromBackupKey attribute.
What should I do?
iOS Data Storage Guidelines quick guide
A lot of people are having this problem and often it seems that the review team is automatically claiming that your app does not follow the iOS Storage Guidelines. Either way you need to document where your app store data and what data is stored where. Here's a quick guide that should get you started.
Your app can store files in either /Documents, /Library or /tmp.
Documents/
Use this directory to store user-generated content. The contents of this directory can be made available to the user through file sharing; therefore, his directory should only contain files that you may wish to expose to the user.
The contents of this directory are backed up by iTunes.
Library/
This is the top-level directory for any files that are not user data files. You typically put files in one of several standard subdirectories. iOS apps commonly use the Application Support and Caches subdirectories; however, you can create custom subdirectories.
Use the Library subdirectories for any files you don’t want exposed to the user. Your app should not use these directories for user data files.
The contents of the Library directory (with the exception of the Caches subdirectory) are backed up by iTunes.
tmp/
Use this directory to write temporary files that do not need to persist between launches of your app. Your app should remove files from this directory when they are no longer needed; however, the system may purge this directory when your app is not running.
The contents of this directory are not backed up by iTunes.
Put user data in Documents/.
This is backed up by iTunes/iCloud
Put app-created support files in the Library/Application support/
This is backed up by iTunes/iCloud
Put temporary data in the tmp/ directory.
This is not backed up by iTunes/iCloud
But how do I find out where my files are stored?
Put the script bellow in func application:didFinishLaunchingWithOptions in your appDelegate file. NSSearchPathDirectory is an enum and represents different folder/locations. Some of them are these.
public enum NSSearchPathDirectory : UInt {
case DocumentDirectory
case LibraryDirectory
}
Change the NSSearhPathDirectory(.DocumentDirectory) to desired locations and check what files you are storing there.
let paths: NSArray = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainsMask, true)
if let documentDirectory = paths.firstObject{
do{
let documents = try NSFileManager.defaultManager().contentsOfDirectoryAtPath(documentDirectory as! String)
for files in documents {
let urlForm = NSURL.fileURLWithPath((documentDirectory as! String) + "/" + files)
do{
try print("\(files): \(urlForm.resourceValuesForKeys([NSURLIsExcludedFromBackupKey])), with filepath: \(urlForm)")
//Prints out folder and files in the desired location
} catch let error as NSError{
print("Can't find key: \(error)")
}
}
}catch let error as NSError{
print("Can't retrieve contents: \(error)")
}
}
My app does not save anything
Lucky you...Write a document to the Apple review team and document your app use of storage. Take screenshots from the logs made out from the script above.
My app saves a lot of user created data
If your app saves a user's data to Documents/ that is fine and write a document documenting that this is made by the user and do follow the iOS Data Storage Guidelines.
If your app downloads data and saves it to the wrong location
Simply follow the iOS Data Storage Guidelines and submit a new binary.
I have files in Documents/ or Library/, but I don't want to back them up
Starting in iOS 5.1, apps can use either NSURLIsExcludedFromBackupKey or kCFURLIsExcludedFromBackupKey file system properties to exclude files and directories from backups. Apps that need to exclude a large number of files can exclude them by creating their own sub-directory and marking that directory as excluded. Apps should create their own directories for exclusion, rather than excluding the system defined directories. Either of these APIs is preferred over the older, deprecated approach of directly setting an extended attribute. All apps running on iOS 5.1 and later should use these APIs to exclude data from backups.
I've created a quick script to handle files that you don't want to backup.
func addSkipBackupAttributeToItemAtPath(filepath: String)-> Bool {
if let url: NSURL = NSURL(fileURLWithPath: filepath) {
let exist = NSFileManager.defaultManager().fileExistsAtPath(String(url))
if exist{
do
{
try url.setResourceValues(["YES" : "NSURLIsExcludedFromBackupKey"])
return true
}
catch let error as NSError
{
print("\(error)")
return false
}
} else
{
print("File does not exist")
return false
}
} else
{
print("Path not recognized")
return false
}
}
If you believe your app's rejection is false write the review team back and explain the situation and your use of storage
Simple guidelines
Bandwidth, network availability, and storage are limited resources and have real, financial consequences for your users. When you design your schema, store in iCloud only information that can’t be re-created.
iCloud-enabled Core Data apps are not only aware of data created on the device, they’re aware of data on other devices. It’s a good idea to keep this fact in mind when designing your Core Data stack.
When you save a managed object context, Core Data creates, in the ubiquity container, a set of transaction changes that are guaranteed to be applied together on other peers. The size of this transaction set, and the frequency with which you save your context, both directly impact the performance of your app.
Resources:
iOS Data Storage Guidelines - Apple Developer
iCloud Programming Guide for Core Data
File System Programming Guide

NSURL URLByResolvingBookmarkData seems to fail randomly

My app is an image viewer for iOS. I allow users to pick files from the camera roll or cloud file providers. For each file chosen, I create a bookmark so that the user to come back to view the file later without having to go through all of the steps of the camera roll/cloud file pickers again. The camera roll bookmarks work consistently, but the cloud file provider bookmarks fail randomly by returning nil from the call to URLByResolvingBookmarkData. The error returned is:
"File Not Found"
This happens with files from iCloud, DropBox, Box, Google Drive, etc. Here is how I create and retrieve the bookmarks:
// bookmark created from url returned by UIDocumentPickerViewController
NSData *bookmark = [url bookmarkDataWithOptions:options includingResourceValuesForKeys:nil relativeToURL:url error: nil];
// retrieving the URL from this bookmark works for a short time, then returns nil
url = [NSURL URLByResolvingBookmarkData:bookmark options:NSURLBookmarkResolutionWithoutUI relativeToURL:nil bookmarkDataIsStale:&isStale error:&error];
Anyone can shed some light as to why a bookmark will work for a while, then fail? Limited storage/RAM?
I have a feeling that the answer is to keep a local copy of files from cloud storage since they're not guaranteed to be accessible more than once.
You should use startAccessingSecurityScopedResource on the URL, making sure to call stopAccessingSecurityScopedResource when you are finished.
Alternatively, Apple highly recommend using FileCoordinator or UIDocument to manage access to files. Especially now you may access files that other apps are also accessing.

Encrypt or protect cached files in the application documents, to be opened only by the application

I'm using EGOCache to cache NSData and then reread the NSData into NSDictionary, so when I checked the iPhone Simulator file to see if the data is protected!! I found that I can open it easily!. So what I am asking about, is there any way to protect or encrypt these (sensitive data)??

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

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.
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");
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.
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.
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.
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
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...!
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?

Is it possible to save files outside of the sandbox via the built-in apps?

If I have a UIWebView which has links to files then is it possible to save those files to disk outside of the application sandbox?
Yes I know an app can't access the filesystem outside of its sandbox, but could the saving process be done by whatever app can handle the file type? - For example if its an audio file, could my app launch QuickTime passing it the file (or file url) and the user is then able to save the file via the QuickTime app saving it in the appropriate location for audio files?
Apps are limited to saving data within their own sandbox. Which you seem to acknowledge already.
You can make one app launch another, which in theory could allow a second app to save data, but within its own sandbox. You also mention this.
In effect, you've answered your own question.
It is possible to write images to the photo album which is outside the sandbox.
UIImage* image = [UIImage imageNamed:#"picture_of_my_cat.png"];
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
In order to get data out from a UIWebView (javascript to objective C) you can subclass NSURLProtocol and use jQuery.ajax.

Resources