Where to store the Core Data file?
The default Core Data for iOS template stores data in an .sqlite
file in the NSDocumentDirectory
. The file is therefor visible if the iDevice is connected to iTunes and file shar开发者_C百科ing is enabled.
I would like to change the directory to something that is not visible to the user and I would choose the NSApplicationSupportDirectory
. Is this the correct directory? What do other developers use?
The best place (on the iPhone) is the Library folder, as described here:
How can I get a writable path on the iPhone?
That directory is meant for things like databases that you do not want the user to be able to see through sharing.
The Application Support directory is a good place to put it, and by convention (from Mac OS X), you should use a subdirectory in Application Support named after your app. For iOS, it doesn't really matter where you put the file, since it's not user-accessible anyways, but keep in mind:
- The Documents directory is visible in iTunes if you've enabled document sharing (or whatever it's called), as you've already found out.
- The Caches directory is not saved when the user installs a new version of your app.
Here is a nice blog post with an implementation for getting the correct Application Support subdirectory: http://cocoawithlove.com/2010/05/finding-or-creating-application-support.html
You can start the file name with a dot (".myData.sqlite") and it will be hidden in the Documents directory. Better yet would be to put in a subfolder ".hidden/" and then you can put whatever you want in there, without worrying about the file names.
I did put my Core-Data-File into a subdirectory of the library directory.
By now I regret this decision. In the next version of my app the database will be accessible for the user again. I will rename it into database.sqlite and put a FAQ entry on my support page which tells the user the purpose of that file.
99.9% of the crashes that occur to my app occur because the database got corrupted in some way. And they can't send me that file, because they can't access it. So I can't find out what went wrong.
This is the code I used to access the private directory. It's in the LibraryDirectory, so iTunes will back it up automatically.
+ (NSString *)createAndReturnDirectory:(NSString *)path {
BOOL isDirectory = NO;
if ([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDirectory]) {
if (isDirectory)
return path;
NSError *error = nil;
if (![[NSFileManager defaultManager] removeItemAtPath:path error:&error]) {
// do something.
return nil;
}
}
NSError *error = nil;
if (![[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error]) {
// do something.
return nil;
}
return path;
}
+ (NSString *)applicationPrivateDocumentsDirectory {
NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
NSString *path = [libraryPath stringByAppendingPathComponent:@"Private Documents"];
return [self createAndReturnDirectory:path];
}
精彩评论