iOS : Apps must follow the iOS Data Storage? - iphone

My iOS app was rejected because I use the /Document directory to store downloaded images.
I will move the downloaded images in the /Library/Caches directory to solve my problem.
But my sqLite database also contains elements manually created by the user.
This file must be copied into the /Library/Caches directory or /Documents directory to be accepted by the Reviewer ?
Sincerely,
Maxime

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.

The data manually created can be stored with in your app directory.
You can use below code to get the current directory -
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
and then append you file name to get the full path.
NSString *fileName = [documentsDirectory stringByAppendingPathComponent:#"myfile.format"] ;

Related

How would you Open PDFs Stored on Your iPhone

I am creating an application that downloads one of its screens as PDF and stores it in a location such as /var/mobile/Applications/B19F4B52-F19B-46F8-9CE0-FA4D4656367B/Documents/SecondScreen1.pdf.. I have no idea what this location is and i want to open this pdf later as well.. Meaning I want the user to be able to easily access his PDFs etc. Which means storing it in a location that is accessible to him. I'd like to know how i can direct a path or manage to store it in some other applications storage (such as photos or so).. Currently this is where i am storing the file i need to store.. -
NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString* documentDirectory = [documentDirectories objectAtIndex:0];
NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:aFilename];
// instructs the mutable data object to write its context to a file on disk
[pdfData writeToFile:documentDirectoryFilename atomically:YES];
You can only store it in your apps sandboxed file hierarchy. The documents folder is usually the recommended one for files that should be exchangeable (to access via iTunes eg). But you can create your own directory too. you can't access other apps file structure. You could use iCloud or Dropbox I suppose.
But to make it accessible to the user, I would store it in documents as you did and enable iTunes file exchange. Also you could easily create a mail composer to send your PDF as email.

What is suitable location for creating sqlite file?

Actually, My app got rejected from app store because i am storing about 9 MB data in document directory.
What is better and suitable location store image cache and to create sqlite database file?
The image cache has to go into the cache directory. A cache should not be included in a backup because you can recreate those images easily.
If the sqlite file stores user data you should put it into the document directory. It has to be included in device backups because you can't recreate it and the user would lose all his data when he restores his device from a backup.
If the sqlite file is downloaded from the web and it is never changed by the user put it into the cache directory too. On iOS 5.0.1 and later you could put that file into the documents directory and set the "Do not backup"-Attribute. However, on device with iOS 5.0 or earlier you HAVE to put that file in the caches directory.
NSString *cacheDirectory = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
The concern area is the iOS 5.0, which supports iCloud, but does not recognizes “do not backup” attribute. In this case, all the data of the app inside documents directory is likely to get backed up to iCloud. For the iOS versions below 5.x:
the iCloud backup is not valid.
the "do not back up" flag is not relevent. It would not produce any warnings during compilation.
Hence the data can be kept in the documents directory, with "do not back up" flag appropiately added to the contents (files/folders), for all the versions. The problem is for the version 5.0 only.
if you have lot of image in Your application.then sotre images in any image store site and use link of image. its better for You.

Will <Application_Home>/Library/Caches be clear on app update?

In my iPhone app I'm caching the raw data of some compressed files to save loading time. But those files may change in an update.
Will iOS clear /Library/Caches for me when the app is updated or I need to clear it myself?
Short:
Will iOS clear /Library/Caches for me when the app is updated
No
Is it possible that iOS does clear everything or parts of Application_Home/Library/Caches during an update? Yes
or I need to clear it myself? You need to ensure what you want to be cleared is cleared.
Be prepared for both situations.
How do you know whether your app got updated? See iOS Application Update Test
Long:
Files Saved During Application Updates When a user downloads an
application update, iTunes installs the update in a new application
directory. It then moves the user’s data files from the old
installation over to the new application directory before deleting the
old installation. Files in the following directories are guaranteed to
be preserved during the update process:
Application_Home/Documents
Application_Home/Library
Although files in other user directories may also be moved over, you
should not rely on them being present after an update.
From Apples Documentation: The Application Runtime Environment - Backup and Restore
Application_Home/Library/Caches Use this directory to write any
application-specific support files that you want to persist between
launches of the application or during application updates. Your
application is generally responsible for adding and removing these
files. It should also be able to re-create these files as needed
because iTunes removes them during a full restoration of the device.
In iOS 2.2 and later, the contents of this directory are not backed up
by iTunes.
From Apples Documentation: The Application Runtime Environment - The File System (daveoncode)
Here an example of when it does clear the cache during an "update":
You install app X V1.0. Lunch it once and the start doing something else. iOS malfunctions and needs to be restored. Developer releases V1.1. You update the app in iTunes on your Mac. You restore your device via iTunes. iTunes installs V1.1. User lunches your app. Your app does not get notified that any of that stuff happened but all files in Application_Home/Library/Cache are gone (iTunes removes them during a full restoration of the device).
Really important information in there: It should also be able to re-create these files as needed. Like Kendall also pointed out it is a cache, so files could be deleted from it by the operating system at any point. So every time you load any file from Application_Home/Library/Caches you have to account for the case that the file isn't there anymore (Kendall touched on this).
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
if(![fileManager fileExistsAtPath:[cachePath stringByAppendingPathComponent:#"myfile.zip"]]) {
//create it, copy it from app bundle, download it etc.
}
//start using it
To be safe, you should clear it yourself. There does not seem to be any documentation stating that it will be cleared for you, so even if it does now you cannot count on it continuing to do so.
The caches directory will be purged if iOS is running out of space. If the user chooses "update all" from the app store options, it is likely that they will run out of space.
You should only store files in the Caches directory if they can be recreated by your app. From what I understand, the media player in iOS7 will only play videos stored in caches directory, and here's how I clear them manually (just in case):
-(void)deleteAllVideos
{
NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSFileManager* fileManager = [NSFileManager defaultManager];
NSArray *directoryContent = [fileManager contentsOfDirectoryAtPath:cachePath error:NULL];
NSError* error;
NSString* fullFilePath = nil;
for(NSString* fileName in directoryContent)
{
if([fileName hasSuffix:#".mp4"])
{
fullFilePath = [cachePath stringByAppendingPathComponent:fileName];
[fileManager removeItemAtPath:fullFilePath error:&error];
if(error)
{
DLog(#"Error: %#",error);
}
}
}
}
It's up to you! Quote from Apple's documentation:
Use this directory to write any application-specific support files
that you want to persist between launches of the application or during
application updates. Your application is generally responsible for
adding and removing these files. It should also be able to re-create
these files as needed because iTunes removes them during a full
restoration of the device. In iOS 2.2 and later, the contents of this
directory are not backed up by iTunes.
The whole point of /Caches is that the system can clear data stored there at any time - if it needs to. You should not worry about clearing out that directory.

How can I store an image in the iPhone device file system so that later if I want I can retrieve it and use in my app?

I am trying to store an image in the device through my program. I am able to store the image in the sandbox. After quitting the app when I run it again the address of the sandbox changes so I am not able to retrieve it and use it in the next run.
Please help.
Have a look at this stackoverflow question.
To get a path to the apps own document path you do
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask,
YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
For a complete description of how to use the filesystem on the iPhone see the documentation here
Files in iPhone OS share space with the user’s media and personal files on the flash-based memory. For security purposes, your application is placed in its own directory and is limited to reading and writing files in that directory only. The following sections describe the structure of an application’s local file system and several techniques for reading and writing files.

Does iPhone API allow application read/write to iPhone's filesystem?

My iPhone app (well, idea of it) needs to do changes to iPhone's filesystem. Does iPhone API allow that?
Your app has its own piece of filesystem that you can read from and write to but you can't access anything outside that, ie you cannot access the filesystem areas of other apps or the OS itself.
Yes Cocoa Touch for iPhone OS allows file access. With the caveat that it naturally only allows file access for files that the current user has read-write permissions to access. Each application runs as single user, and really only have access to it's own small sandbox of files. So you will not be able to access system files, or files from another application.
There are two main directories that you might want your app to access:
NSDocumentDirectory - Analogous to you own Documents folder, the contents of this folder is backed up when you synch the device.
NSCachesDirectory - This one resides in /Library/Caches/ and is not backed up when synching the device.
You get the path to these directories using the NSSearchPathForDirectoriesInDomains function. When searching you will get an array of potential paths, it is safe to use the first path as long as you only search in the user domain. For example:
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString* docsPath = [paths objectAtIndex:0];
Once you have a path you can work away with your files using the default file manager. For example remove a file:
NSFileManager* fm = [NSFileManager defaultManager];
[fm removeItemAtPath:filePath error:NULL];
i just wrote a tutorial on how to do this using NSMutableArrays that you can check out that should help you. http://idevkit.com/iphonedev/2009/09/saving-nsmutablearrays/
if you have anymore questions on it lemme know and ill add to it