I am using iTunes file sharing in my app, and need to put Core Data's sqlite database elsewhere so that users don't fiddle with it. I have read a previous SO post regarding the best way to hide the sqlite file that Core Data uses.
There seems to be conflicting opinions regarding whether to put the database in Library/Preferences or in a directory called .data
, but I think I agree the best approach is to use the .data
directory.
There is currently an -applicationDocumentsDirectory
method that was provided by the Core Data template code:
- (NSString *)applicationDocumentsDirectory {
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}
I would like to implement a function called applicationHiddenDocumentsDirectory
that will give me access to the ".data" subdirectory, but I don't know enough about Objective-C or the Cocoa/Foundation frameworks to access the directory.
Could someone help me implement this method please?
Thanks!
==Rowan==
how do you like this one? You have to add appropriate action if an error occurs.
EDIT: I changed this so the database is saved in the library-directory, which is backed up by itunes and not visible to the user. This was suggested by Apple Q&A
- (NSString *)applicationHiddenDocumentsDirectory {
// NSString *path = [[self applicationDocumentsDirectory] stringByAppendingPathComponent:@".data"];
NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
NSString *path = [libraryPath stringByAppendingPathComponent:@"Private Documents"];
BOOL isDirectory = NO;
if ([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDirectory]) {
if (isDirectory)
return path;
else {
// Handle error. ".data" is a file which should not be there...
[NSException raise:@".data exists, and is a file" format:@"Path: %@", path];
// NSError *error = nil;
// if (![[NSFileManager defaultManager] removeItemAtPath:path error:&error]) {
// [NSException raise:@"could not remove file" format:@"Path: %@", path];
// }
}
}
NSError *error = nil;
if (![[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error]) {
// Handle error.
[NSException raise:@"Failed creating directory" format:@"[%@], %@", path, error];
}
return path;
}
As new CoreData templates return NSURL objects rather than NSString path, here is my updated version of the above code :
- (NSURL *)applicationHiddenDocumentsDirectory {
// NSString *path = [[self applicationDocumentsDirectory] stringByAppendingPathComponent:@".data"];
NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
NSString *path = [libraryPath stringByAppendingPathComponent:@"Private Documents"];
NSURL *pathURL = [NSURL fileURLWithPath:path];
BOOL isDirectory = NO;
if ([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDirectory]) {
if (isDirectory) {
return pathURL;
} else {
// Handle error. ".data" is a file which should not be there...
[NSException raise:@"'Private Documents' exists, and is a file" format:@"Path: %@", path];
// NSError *error = nil;
// if (![[NSFileManager defaultManager] removeItemAtPath:path error:&error]) {
// [NSException raise:@"could not remove file" format:@"Path: %@", path];
// }
}
}
NSError *error = nil;
if (![[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error]) {
// Handle error.
[NSException raise:@"Failed creating directory" format:@"[%@], %@", path, error];
}
return pathURL;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With