sqlcipher stopped working in iOS 10 - ios

I have use Sqlite (sqlcipher) in my iOS project for database. In iOS 9 all things are working perfectly. Now i have update new Xcode. But DB encryption is not working now.
sqlite3 *db1;
if (sqlite3_open([[self.databaseURL path] UTF8String], &db1) == SQLITE_OK) {
const char* key = [g_sqlite_key UTF8String];
AZLog(#"%s",key);
sqlite3_key(db1, key, (int)strlen(key));
if (sqlite3_exec(db1, (const char*) "SELECT count(*) FROM sqlite_master;", NULL, NULL, NULL) == SQLITE_OK) {
AZLog(#"Password is correct, or a new database has been initialized");
} else {
AZLog(#"Incorrect password!");
}
sqlite3_close(db1);
}
Can anyone help me ?
Thanks in advance

You have to provide readwrite and open-create permission while encryption of database using sqlcipher.
sqlite3 *db1;
if (sqlite3_open_v2([[self.databaseURL path] UTF8String], &db1, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL) == SQLITE_OK) {
const char* key = [g_sqlite_key UTF8String];
AZLog(#"%s",key);
sqlite3_key(db1, key, (int)strlen(key));
if (sqlite3_exec(db1, (const char*) "SELECT count(*) FROM sqlite_master;", NULL, NULL, NULL) == SQLITE_OK) {
AZLog(#"Password is correct, or a new database has been initialized");
} else {
AZLog(#"Incorrect password!");
}
sqlite3_close(db1);
}

There were many changes with Xcode 8 and the new SDKs. Please refer to this guidance:
https://discuss.zetetic.net/t/important-advisory-sqlcipher-with-xcode-8-and-new-sdks/1688

Related

UITextview Save to Sqlite iOS 9 Not Working

I have an application that uses Sqlite as the db. This app has worked for a few years with no problem. With the release of iOS 9, I cannot save any of the UITextviews to the database. Everything else still saves with no problems. The app returns no error when saving and it looks like everything works, but when I look in the database the fields have null values for any data that is a blob. Does anyone know what the issue is?
This is not much help because this problem is with all my apps now with iOS 9 and UITextview saving. Here's a snippet of code:
sqlite3_stmt *statement;
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &BratAppsDB) == SQLITE_OK) {
const char* sqliteQuery = "UPDATE MyDatabase SET TheTextView=? Where ID='1'";
if (sqlite3_prepare_v2(BratAppsDB, sqliteQuery, -1, &statement, NULL) == SQLITE_OK) {
sqlite3_bind_blob(statement, 1, [TheUITextView.text UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_step(statement);
sqlite3_reset(statement);
} else {
NSLog(#"Error is: %s", sqlite3_errmsg(BratAppsDB));
}
sqlite3_finalize(statement);
sqlite3_close(MyDB);
}
Don't use "-1", put the length:
sqlite3_bind_blob(statement, 1, [TheUITextView.text UTF8String], (int)TheUITextView.text.length, SQLITE_TRANSIENT);
JP

Move unencrypted tables to encrypted sqlite database

I want to know how to transfer my unencrypted sqlite tables to encrypted sqlite database. I'm using sqlcipher to encrypt a database.
I've tried this code, but it didn't work.
NSString *databasePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]
stringByAppendingPathComponent: #"contacts_enc.sqlite"];
sqlite3 *db;
if (sqlite3_open([databasePath UTF8String], &db) == SQLITE_OK) {
const char* key = [#"1234" UTF8String];
sqlite3_key(db, key, strlen(key));
if (sqlite3_exec(db, (const char*) "SELECT count(*) FROM sqlite_master", NULL, NULL, NULL) == SQLITE_OK) {
NSLog(#"password is correct, or, database has been initialized") ;
//START
sqlite3_exec(db, "ATTACH DATABASE 'contacts.sqlite' AS encrypted KEY '1234';", NULL, NULL, NULL);
sqlite3_exec(db, "CREATE TABLE encrypted.account(_id,username,password);", NULL, NULL, NULL);
sqlite3_exec(db, "INSERT INTO encrypted.account SELECT * FROM account;", NULL, NULL, NULL);
sqlite3_exec(db, "DETACH DATABASE encrypted;", NULL, NULL, NULL);
//END
}
}
SQLCipher provides a convenience function called sqlcipher_export(…) that will duplicate the contents of your database to another attached database. For your scenario, please review example 1 found here within the documentation.

Delete row from SQLLite database

I am trying to delete a row from my database "Code mentioned below", however it never deletes the row and the prepare statement also never seems to be called.
I can insert and update ok but for the life of me can't figure this out..
barcode is a string variable passed to the method from a editable tableview.
I can see the correct values when I log the deletSQL string but record is actually never removed.
For further info the barcode in the database is a primary key.
Also database paths are all correct and its calling the right db file.
Its just the delete function that is not working...
-(void)delete:(NSString *)barcode{
const char *dbpath = [databasePath3 UTF8String];
if (sqlite3_open(dbpath, &database3) == SQLITE_OK)
{
NSLog(#"Opened OK");
NSString *deleteSQL = [NSString stringWithFormat: #"delete from assets where assetBarcode=\"%#\'",barcode];
NSLog(#"%#",deleteSQL);
const char *sql = [deleteSQL UTF8String];
if(sqlite3_prepare_v2(database3, sql, 1, &deleteStatement, NULL) == SQLITE_OK)
{
NSLog(#"SQL OK?");
if (sqlite3_step(deleteStatement) == SQLITE_ROW)
{
sqlite3_bind_text(deleteStatement, 1, [barcode UTF8String], -1, SQLITE_TRANSIENT);
}
}
else{
NSLog(#"WHAAAATTTTT");
}
}
sqlite3_step(deleteStatement);
sqlite3_reset(deleteStatement);
sqlite3_close(database3);
}
the barcode columne in the database appears to be of type varchar
try this
-(void)delete:(NSString *)barcode {
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK)
{
if(deleteStatement == nil)
{
const char *sql = "DELETE FROM assets WHERE assetBarcode = ?";
if(sqlite3_prepare_v2(database, sql, -1, & deleteStatement, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating delete statement. '%s'", sqlite3_errmsg(database));
}
sqlite3_bind_text(deleteStatement, 1, [barcode UTF8String], -1, SQLITE_TRANSIENT);
if(SQLITE_DONE != sqlite3_step(deleteStatement))
NSAssert1(0, #"Error while deleting data. '%s'", sqlite3_errmsg(database));
else
//SQLite provides a method to get the last primary key inserted by using sqlite3_last_insert_rowid
//noteID = sqlite3_last_insert_rowid(database);
//Reset the delete statement.
sqlite3_reset(deleteStatement);
sqlite3_close(database);
deleteStatement = nil;
}
else
sqlite3_close(database);
}
Regarding the SQL string...
delete from assets where assetBarcode=\"%#\'
The parameter is being opened with a quote and closed with a single quote. Use either double or single quotes for both. Perhaps this is related to your issue?

Retrieving REAL value from SQLite table

I am trying to build a converter-like app between different measurement units. At the moment, I am using SQLite and I've got a table that includes different units alongside corresponding rates.
Inside my app I've got the following functions to retrieve rate values depending on selected units:
+(float)rateFrom:(NSString *)from to:(NSString *)to{
if (sqlite3_open([sqlPath UTF8String], &database) == SQLITE_OK) {
const char *sql = [[NSString stringWithFormat:#"SELECT %# FROM Units WHERE code = '%#'", to, from] UTF8String];
sqlite3_stmt *selectstmt;
if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) {
return (float)sqlite3_column_double(selectstmt, 0);
}
}
else{
sqlite3_close(database);
}
return -1;
}
The problem is that the return rate is 0.00
I've tried the constructed query directly on my Terminal window and returns correct values
I've tried NSNumber and initWithFloat: with no success too.
Could anyone explain me what am I doing wrong here?
Thanks in advance.
You're never actually executing the query. sqlite3_prepare_v2 "compiles" the query, but doesn't actually run it. You're probably going to want to call sqlite3_step to actually execute the query. You're also not calling sqlite3_finalize on your compiled statement, so you're also leaking memory with this code. This might help:
+ (float)rateFrom:(NSString *)from to:(NSString *)to
{
float retVal = -1;
if (sqlite3_open([sqlPath UTF8String], &database) == SQLITE_OK) {
const char *sql = [[NSString stringWithFormat:#"SELECT %# FROM Units WHERE code = '%#'", to, from] UTF8String];
sqlite3_stmt *selectstmt;
if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK &&
sqlite3_step(selectstmt) == SQLITE_ROW) {
retVal = (float)sqlite3_column_double(selectstmt, 0);
}
if (selectstmt) {
sqlite3_finalize(selectstmt);
}
sqlite3_close(database);
database = NULL;
}
return retVal;
}
Also, while were at it, if the strings in to and from come from user input, you probably don't want to use them literally in queries, as this is vulnerable to SQL injection attacks.
You could also consider using FMDB which is a nice Objective-C wrapper for the SQLite API.

When I try SQLite on iOS, INSERT and UPDATE does not work

I createed a table in user.db, this file is in my xcode project folder.
create table user (uid INTEGER PRIMARY KEY ASC AUTOINCREMENT, username, mobile);
Next, in the app delegate .m file, I insert two rows, then I query select * from user and print it.
However, use statement and sqlite3_exec, the insertions are not successful, and there are no errors at all. user.db has 3 rows I inserted from sqlite command line. When I run this app, it prints 5 rows of data, 2 rows are inserted by me, but when I query in sqlite command line, there are still 3 rows, the two newer rows are not committed?
I also run sqlite3_get_autocommit, and find out autocommit=1, so what have I missed to cause this to happen?
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
[self.window makeKeyAndVisible];
NSString* file = [[NSBundle mainBundle] pathForResource:#"user" ofType:#"db"];
sqlite3* database = NULL;
if(sqlite3_open([file UTF8String], &database) == SQLITE_OK)
{
NSLog(#"database open successfully.");
// stmt
// int autocommit = sqlite3_get_autocommit(database);
sqlite3_stmt* stmt;
static char * sql = "insert into user (username, mobile) values('xxxx', '5555555');commit;";
int success = sqlite3_prepare_v2(database, sql, -1, &stmt, NULL);
if(success != SQLITE_OK)
{
NSLog(#"create stmt failed");
}
success = sqlite3_step(stmt);
if(success != SQLITE_OK)
{
NSLog(#"insert failed");
}
sqlite3_finalize(stmt);
sqlite3_exec(database, "begin;insert into user (username, mobile) values('yyyy', '666666');commit;", NULL, NULL, 0);
// insert
char *zErrMsg = 0;
int rc = sqlite3_exec(database, "select * from user", MyCallback, 0, &zErrMsg);
if(rc != SQLITE_OK)
{
fprintf(stderr, "SQL error: %s\n", zErrMsg);
}
}
sqlite3_close(database);
return YES;
}
You can't update databases stored in the app resources. Try copying the database to your app's Document or Library folder and then updating the database there.

Resources