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
Related
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.
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"] ;
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.
I have a game where each level has its own logic, so it is a module with level-specific code and graphics.
I am confused on whether its possible to download and integrate dynamically in the app each level.
Searching the web, I found that nsbundle is the standard way for performing this task, however loadable bundles are not supported in iOS.
Is there a way to approach such a task,and if yes, it is not even clear to me if it is even permitted by Apple
Why do not you want just hide all extra levels in your app and unlock/show them instead of downloading?
By the way, apple will not allow you plugging in any code that is not approved by them.
Downloading code is not allowed by the App Store rules.
Thechnically, it's possible by simply saving the files you want into the document folder of your app.
You can get this path with:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
Then use whatever API to write your levels there.
Now while you are allowed to download additional assets, you are not allowed to download additional code. But I'm unclear on this, I know an app that download some .lua script files and never had any trouble with Apple. For the legal side, you'll have to trust someone else.
EDIT: By code, I mean compiled code (like a dylib), while using dlopen of the iPhone may work, it's not allowed or documented.
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.