Итак, я вот уже неделю как бьюсь головой об стену.
Я пишу приложение для iPhone, в котором есть база данных sqlite. Я могу открыть базу данных и читать из нее (я помещаю туда несколько тестовых данных через командную строку / терминал), выбирать конкретные данные и т. Д. Но я не могу вставить телефон в базу данных. Когда я выполняю sqlite3_exec (...), он возвращает код ошибки 8 «попытка записи базы данных только для чтения».
Я читал здесь другие вопросы о том, что я использую базу данных Main Bundle, а не базу данных пользователей, и что симулятор часто будет просто «позволять вам это делать», в то время как на живом устройстве вы получите ошибку , Ну, это не то, что происходит в моем случае - я получаю эту ошибку при работе на симуляторе. И из того, что я могу сказать, мой код для проверки базы данных точно так же, как многие другие рекомендуют это.
Вот код, который я использую, чтобы убедиться, что база данных существует, а если нет, я копирую ее:
// initialize db (if not already)
+(void) checkDatabase {
// setup some variables
Boolean success;
dbName = @"daarma.sqlite";
NSArray *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDirectory, YES);
// I have tried this with both NSUserDirectory and NSUserDomainMask, desn't seem to make a difference
NSString *documentsDir = [documentPath objectAtIndex:0];
dbPath = [documentsDir stringByAppendingPathComponent:dbName];
// dbPath = [[NSBundle mainBundle] pathForResource:@"daarma" ofType:@"sqlite"];
// check to see if the database already exists
NSFileManager *fm = [NSFileManager defaultManager];
success = [fm fileExistsAtPath:dbPath];
if(success) {
NSLog(@"Database exists, returning.");
return;
}
// if not, we create it
NSLog(@"Creating database in user profile...");
NSString *dbPathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:dbName];
[fm copyItemAtPath:dbPathFromApp toPath:dbPath error:nil];
[fm release];
[documentPath release];
[documentsDir release];
}
Когда я иду, чтобы вставить данные, используя это:
sqlite3 *db;
int open = sqlite3_open_v2([dbPath UTF8String], &db, -1, NULL);
if(open == 0) {
NSLog(@"open, inserting");
NSString *sql = [NSString stringWithFormat:@"insert into affiliates values('1','2','3','4','5','6','7','8','9','10','11','12')"];
int exec = sqlite3_exec(db, [sql UTF8String], NULL, NULL, NULL);
NSLog(@"exec = %d",exec);
}
sqlite3_close(db);
exec возвращает с указанным выше кодом ошибки 8: "" попытка записи базы данных только для чтения. "
Я также попробовал обычный перезапуск, очистку проекта, сброс данных симулятора. Я даже зашел в каталог Simulator и удалил все данные приложения вручную. Когда я попытался вернуться, он обнаружил, что базы данных не было, и скопировал ее, но я все еще получаю эту ошибку.
EDIT:
Я только что заметил, что если я делаю это в методе checkDatabase:
NSError *error;
[fm copyItemAtPath:dbPathFromApp toPath:dbPath error:&error];
NSLog(@"error = %@",error);
это вызывает сбой симулятора при первом повороте (после сброса содержимого), но каждый раз после этого он возобновляет вышеуказанную ошибку без сбоев. Так что, возможно, я делаю что-то не так с моим методом checkDatabase. ?? :( Он никогда не сообщает мне вывод сообщения об ошибке.