Thursday, 30 August 2012

iOS Application Directory Structure : Document, Cache and tmp

Hello friends!!

In this post i am going to talk about iOS application directory structure. iOS applications run in sandbox like environment that means Application (A) can not access the resources of Application(B). In more easy words i can say that a closed room is allocated to each Application where they have to eat and sleep, of course  room is closed so they can not access resources of each other. However an Application can request Operating System( OS ) to run other Application. Following image shows directory structure of a typical iOS application.


Apple reserve all rights to change the directory structure and you may find different structure on different OS version for example  "Libarary/ Application Support " does not exists in iOS 5 and older versions. Most important directories are app bundle(myApp.app), Document, cache and tmp. 
             When our Application is installed on iPhone, iTunes creates a home directory(In above image "App" is home directory) for application. This directory is same as closed room(ad discussed above) for the App. It contains everything that Application can access. Applications can create file, delete file under home directory. 
            You should be selective while storing file in directories because wrong selection of directory may affect the iCloud syncing process and waste the user space, that encourage the user to delete your App. So you should be selective to where you place which file.  
           iOS uses a unique ID instead of application name, so you can not give absolute or relative path of any directory. 
Now let me describe the usage of directories and code to access these directories. 

Bundle Directory(myApp.app) -

     This is the place(bundle) where your App exists. You should not modify this directory, it prevent your app from launching again. All resources you put in your project will stored in this directory. How to get the path of bundel directory -
//get the main bundel 
NSBundle *bundle = [NSBundle mainBundle];
//get the path of home directory 
NSString *bundlePath = [bundle bundlePath];
 You can find the path of your resources by appending resource name to bundlePath or  as follows
//Find the path of a image(myPhoto.png)
NSString *pathTomyPhoto = [[NSBundle mainBundle] pathForResource:@"myPhoto" ofType:@"png"];
NSLog(@"\n%@\n",pathTomyPhoto);

OUTPUT-
.../Applications/99C1AFFA-0908-4968-B6C7-E2644385D86D/appName.app/myPhoto.png

To protect this directory from tempering iOS sign it with unique id, any modification in this ID prevent your app from launching.

Document Directory

Use this directory to store important files of your application like sqlite database. Data of this directory is backup in iTunes so don't store temporary and large fiels. If you will store large amount of data in document directory, Apple may reject your App see this. In more general you should store only those data which can not be recreated by your app.  How to get the path of document directory?

/*use following c function to find any directory, just you need to provide the directory type*/
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
//find the actual path
NSString* docDir = [paths objectAtIndex:0];
NSLog(@"\n%@\n",docDir);

Document/Inbox Directory 

This directory is used by other applications to open files with the help of your application. For example email app places email attachement in inbox directory before opening the attachement with the help of your application. We have only read and delete permission on this directory means we can not create new file or edit fiels in this directory. If you want to edit any file, then you must move that file to document or other directory. You can access this directory by adding a path component "Inbox" to document directory path.

Library Directory

This directory is used to store app specific files. Content of this directory is also backup in iTunes but not exposed to user. You should not store user specific files in directory. iOS applications are not permitted to use this directory although you can use the subdirectories of this directory. 

NOTE: data of cache directory is not backup in iTunes. 

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *libDirectory = [paths objectAtIndex:0];
NSLog(@"%@",libDirectory);

Library/Caches Directory

Content of this directory is not backup by the iTunes. You should store only those files which can be recreated easily. System may delete content of this directory (to free up the disk space) when it is required, so your app should gracefully handel this type of situations  Eligible candidate of this directory are downloadable contents, database cache files etc . You can create, edit, delete content of this directory. You can get the path of cache directory as follows -
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachesDirectory = [paths objectAtIndex:0];
NSLog(@"%@",cachesDirectory);

Library/Application Support Directory

This directory was introduced in iOS 5.0.1 and content of this directory is also backup in iTunes. You can use this directory to store App created fiels, templates for example we can store newly purchased levels of game in this directory. You can find the path of this directory by passing "NSApplicationSupportDirectory" as searchPathDirectory in "NSSearchPathForDirectoriesInDomains" method.

Library/Preferences Directory

Apple recommend us to not create any file in this directory and instead of this we should use "NSUserDefault" class to set and get preference values of our APP. Purpose of this directory is to store app preference files, generally our app creates files in this directory. You can set preference values in user default as follows -
//get user default object
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
    
//set values in user default
[userDefault setValue:@"mithi" forKey:@"nickname"];
[userDefault setBool:NO forKey:@"shoulShowDOB"];
[userDefault synchronize];
    
//get values from user default
NSString *nickName = [userDefault valueForKey:@"nickname"];
NSLog(@"Nickname = %@",nickName);
BOOL shouldShowDOB = [userDefault boolForKey:@"shoulShowDOB"];
    
if (shouldShowDOB) {
    NSLog(@"We have permission to show DOB");
}else {
    NSLog(@"We do not have permission to show DOB");
}

tmp Directory

Last but not least tmp directory is use to store temporary files, you should use this directory to store those files which are not required to persist or required for a few time. You should delete the files when that is not required. Content of this directory can be deleted any time. You can get the path of this directory as follows -
NSString *tmpDirectory = NSTemporaryDirectory();
NSLog(@"%@",tmpDirectory);

Don't forget to leave your valuable comments!! bye bye!!