project-imas / encrypted-core-data

v2.0 - iOS Core Data encrypted SQLite store using SQLCipher
Other
785 stars 236 forks source link

Messy complex method makeStoreWithOptions #267

Closed lolgear closed 7 years ago

lolgear commented 7 years ago

Well, it seems that this method take care of everything.

Also it is hard to adopt framework to NSPersistentStoreContainer.

And its name:

+ (NSPersistentStoreCoordinator *)makeStoreWithOptions:(NSDictionary *)options managedObjectModel:(NSManagedObjectModel *)objModel error:(NSError *__autoreleasing *)error
  1. It creates coordinator. ( Why?! )

    NSPersistentStoreCoordinator * persistentCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:objModel];
  2. It handles all stuff related to database file on disk.

    BOOL backup = YES;
    NSURL *databaseURL;
    id dburl = [options objectForKey:EncryptedStoreDatabaseLocation];
    if(dburl != nil) {
        if ([dburl isKindOfClass:[NSString class]]){
            databaseURL = [NSURL URLWithString:[options objectForKey:EncryptedStoreDatabaseLocation]];
            backup = NO;
        }
        else if ([dburl isKindOfClass:[NSURL class]]){
            databaseURL = dburl;
            backup = NO;
        }
    }

    if (databaseURL)
    {
        NSMutableDictionary *fileAttributes = [options mutableCopy];
        [fileAttributes removeObjectsForKeys:@[EncryptedStorePassphraseKey, EncryptedStoreDatabaseLocation]];

        [[NSFileManager defaultManager] setAttributes:[fileAttributes copy] ofItemAtPath:[databaseURL absoluteString] error:nil];
    }
  1. It relies on main bundle in backup ( which is incorrect, cause database could exist in Database framework )
    if (backup){
        NSString *dbNameKey = (__bridge NSString *)kCFBundleNameKey;
        NSString *dbName = NSBundle.mainBundle.infoDictionary[dbNameKey];
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSURL *applicationSupportURL = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
        [fileManager createDirectoryAtURL:applicationSupportURL withIntermediateDirectories:NO attributes:nil error:nil];
        databaseURL = [applicationSupportURL URLByAppendingPathComponent:[dbName stringByAppendingString:@".sqlite"]];

    }
  1. It ignores custom configurations.
    [persistentCoordinator addPersistentStoreWithType:EncryptedStoreType configuration:nil URL:databaseURL
        options:options error:error];
  1. It ignores fileManager operations errors. ( Why?! )

I suppose that this method should be split apart into several smaller methods. For example, it would be great to have EncryptedFileManager or something like this. This manager will handle encrypted fileManager part.

And also it would be great to have simple method that doesn't rely on NSPersistentCoordinator value at the end.

One of these methods could 'bless coordinator' with this store at url.

lolgear commented 7 years ago

@DanielBroad please, have a look at PR

lolgear commented 7 years ago

@DanielBroad build fixed, please, check it. thanks!

lolgear commented 7 years ago

done! successfully integrated in database framework in swift project.