2015-08-16 88 views
0

tutorial適用於以下代碼段。iOS sqlcipher fmdb「文件已加密或不是數據庫」

pod 'FMDB/SQLCipher' 

...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
... 

    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentDir = [documentPaths objectAtIndex:0]; 
    self.databasePath = [documentDir stringByAppendingPathComponent:@"gameDefault.sqlite"]; 

    [self createAndCheckDatabase]; 

... 
} 

...

-(void) createAndCheckDatabase 
{ 
    BOOL success; 

    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    success = [fileManager fileExistsAtPath:self.databasePath]; 

    if(success) return; // If file exists, dont do anything 

    // if file does not exist, make a copy of the one in the Resources folder 
    NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"gameDefault.sqlite"]; // File path 

    [fileManager copyItemAtPath:databasePathFromApp toPath:self.databasePath error:nil]; // Make a copy of the file in the Documents folder 

    // Set the new encrypted database path to be in the Documents Folder 
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentDir = [documentPaths objectAtIndex:0]; 
    NSString *ecDB = [documentDir stringByAppendingPathComponent:@"encrypted.sqlite"]; 

    // SQL Query. NOTE THAT DATABASE IS THE FULL PATH NOT ONLY THE NAME 
    const char* sqlQ = [[NSString stringWithFormat:@"ATTACH DATABASE '%@' AS encrypted KEY 'secretKey';",ecDB] UTF8String]; 

    sqlite3 *unencrypted_DB;  
    if (sqlite3_open([self.databasePath UTF8String], &unencrypted_DB) == SQLITE_OK) { 

     // Attach empty encrypted database to unencrypted database 
     sqlite3_exec(unencrypted_DB, sqlQ, NULL, NULL, NULL); 

     // export database 
     sqlite3_exec(unencrypted_DB, "SELECT sqlcipher_export('encrypted');", NULL, NULL, NULL); 

     // Detach encrypted database 
     sqlite3_exec(unencrypted_DB, "DETACH DATABASE encrypted;", NULL, NULL, NULL); 

     sqlite3_close(unencrypted_DB); 
    } else { 
     sqlite3_close(unencrypted_DB); 
     NSAssert1(NO, @"Failed to open database with message '%s'.", sqlite3_errmsg(unencrypted_DB)); 
    } 

    self.databasePath = [documentDir stringByAppendingPathComponent:@"encrypted.sqlite"]; 
} 

...

[db setKey:@"secretKey"] 

...

// FMDatabase 
    FMDatabase *db = [FMDatabase databaseWithPath:[self getDatabasePath]]; 
    [db open]; 
    [db setKey:@"secretKey"]; 

    // FMDatabaseQueue 
    FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:[self getDatabasePath]]; 

    [queue inDatabase:^(FMDatabase *db) { 
     [db setKey:@"secretKey"]; 
     ... 
    }]; 

...

當我在我的其他項目中使用相同的代碼時,它可以正常加密現有的sqlite數據庫。 但是,當我嘗試通過sql選擇查詢訪問表時,我得到錯誤,「文件被加密或不是數據庫」。雖然,教程應用程序沒有問題,我可以在那裏更新/插入/刪除/選擇記錄。任何線索?

回答

1

我已經修好了。如前所述,相同的代碼行爲不同,因此設置可能有問題。在我的應用程序,我加入了SQLCipher和FMDB如下:

pod 'SQLCipher', '~> 3.1' 
pod 'FMDB', '~> 2.5' 

而在該教程他們被添加爲

pod 'FMDB/SQLCipher' 

雖然,該吊艙命令下載SQLCipher和FMDB的版本相同的每個這裏顯示的終端輸出

Updating local specs repositories 
Analyzing dependencies 
Downloading dependencies 
Installing FMDB (2.5) 
Installing SQLCipher (3.1.0) 
Generating Pods project 
Integrating client project 

所以,我改變了像教程那樣的pod命令,並且錯誤是固定的。雖然,我不知道這些命令有什麼不同。

+1

[該FMDB/SQLCipher subspec聲明SQLCipher作爲依賴,讓FMDB與-DSQLITE_HAS_CODEC標誌進行編譯。( https://github.com/ccgus/fmdb#cocoapods)更確切地說,[這一行](https://github.com/ccgus/fmdb/blob/master/FMDB.podspec#L42)。 –

+0

是的,這是有道理的。 – zeeawan

2

我已經修復了。我認爲FMDB & SQLCipher存在一些inter pod依賴性。我已經使用下面的鏈接解決了這個問題。現在成功地利用SQLCipher與FMDB我的數據庫文件加密.... :-D

How to Use FMDB With SQLCipher?

相關問題