Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hide Core Data sqlite file when iTunes File Sharing is Enabled

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==

like image 468
Rowan McQueen Avatar asked Oct 05 '10 14:10

Rowan McQueen


2 Answers

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;
}
like image 164
Matthias Bauch Avatar answered Oct 25 '22 05:10

Matthias Bauch


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;
}
like image 31
Dirty Henry Avatar answered Oct 25 '22 05:10

Dirty Henry