Невозможно скопировать базу данных через

Я ориентируюсь на iOS 5.1 и пытаюсь скопировать базу данных из файлов моего приложения в папку «Документы». Я делал это с тем же кодом в приложениях в прошлом, поэтому я немного запутался, почему на этот раз он не работает.

Это метод, который я использую, чтобы проверить, существует ли он, и скопировать его, если это не так. Это из здесь .

-(void) checkAndCreateDatabase{
// Check if the SQL database has already been saved to the users phone, if not then copy it over
BOOL success;

// Create a FileManager object, we will use this to check the status
// of the database and to copy it over if required
NSFileManager *fileManager = [NSFileManager defaultManager];

// Check if the database has already been created in the users filesystem
success = [fileManager fileExistsAtPath:self.databasePath];

// If the database already exists then return without doing anything
if(success) return;

NSLog(@"Installing db: %@", self.databasePath);
// If not then proceed to copy the database from the application to the users filesystem

// Get the path to the database in the application package
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];

// Copy the database from the package to the users filesystem
[fileManager copyItemAtPath:databasePathFromApp toPath:self.databasePath error:nil];

//[databasePathFromApp release];
//[fileManager release];

}

Когда я пытаюсь запросить БД, я делаю это так:

sqlite3 *database1; 

// Open the database from the users filessytem
if(sqlite3_open([self.databasePath UTF8String], &database1) == SQLITE_OK) {
    // Setup the SQL Statement and compile it for faster access

    NSString *sqlStatement = [NSString stringWithFormat: @"update login set is_logged=0"];
    sqlite3_stmt *compiledStatement;

    if(sqlite3_prepare_v2(database1, [sqlStatement UTF8String], -1, &compiledStatement, NULL) == SQLITE_OK) {

        if(SQLITE_DONE != sqlite3_step(compiledStatement)){
            NSAssert1(0, @"Error while updating logged. '%s'", sqlite3_errmsg(database1));
            NSLog(@"Error setting logged_in to 0: %s", sqlite3_errmsg(database1));
        }
        else{
            NSLog(@"Made Logged_in=0");
        }
    }
    else{
        NSLog(@"Prop problem1: %s", sqlite3_errmsg(database1));
        NSLog(@"Couldn't prep 1");
    }
    // Release the compiled statement from memory
    sqlite3_finalize(compiledStatement);
}
else{

    NSLog(@"Couldn't even open db1");
}
sqlite3_close(database1);

Функция sqlite3_open() возвращает false в этом случае с sqlite3_errmsg из no such table: login.

У меня есть функция, которая вызывается каждую секунду и создает объект, использующий этот объект базы данных. Может ли быть так, что база данных не была скопирована в эту секунду, и следующий вызов прерывает предыдущую копию? Это маловероятно.

Есть идеи, в чем может быть проблема?

Решение Я проконсультировался по этому вопросу: здесь и согласно пункту № 2 кажется, что моей базы данных не было в списке «Копировать ресурсы пакета». Я добавил его, и теперь все выглядит нормально.

Спасибо, что заставили меня думать в правильном направлении, ребята.


person emachine    schedule 14.03.2012    source источник
comment
Используйте Организатор, чтобы загрузить файлы с телефона и посмотреть, что скопировано. (Кроме того, имейте в виду, что вам, вероятно, потребуется пометить файл БД как не резервный, чтобы обойти новые стандарты Apple 5.1.)   -  person Hot Licks    schedule 14.03.2012
comment
Он отображается в папке «Документы», но содержимое пустое. Я бы предположил, что это связано с проблемой кодирования файла sql?   -  person emachine    schedule 14.03.2012
comment
Сотрите это, я просто удалил приложение и переустановил, а базы данных нет в папке «Документы». Кажется, что [пустой] файл базы данных появляется только после того, как я пытаюсь его запросить.   -  person emachine    schedule 14.03.2012
comment
Да, Sqlite создаст файл, если его нет. Дважды проверьте, что вы копируете ИЗ нужного места и т. д.   -  person Hot Licks    schedule 14.03.2012


Ответы (1)


Попробуйте убедиться, что каждый этап вашей процедуры копирования возвращает действительный объект. Возможно, (например) вы не включаете расширение при поиске пути к ресурсу. Я предпочитаю функцию NSBundle pathForResource:ofType для получения материалов из пакета. Кроме того, что касается пустой БД, функция открытия sqlite создает базу данных, если она не существует, и открывает ее. Попробуйте получить ошибку от copyItemAtPath

person borrrden    schedule 14.03.2012
comment
Ошибка: Error Domain=NSCocoaErrorDomain Code=260 Операция не может быть завершена. (Ошибка какао 260). Данный файл или каталог отсутствует} - person emachine; 14.03.2012
comment
Когда я использую [[NSBundle mainBundle] pathForResource:@myappdb ofType:@sql] я получаю эту ошибку - Завершение приложения из-за необработанного исключения "NSInvalidArgumentException", причина: "*** - [NSFileManager copyItemAtPath:toPath:error:]: источник путь нулевой - person emachine; 14.03.2012
comment
Поэтому мне кажется, что моя проблема - это путь, который я использую, чтобы получить исходную базу данных в моей папке ресурсов... - person emachine; 14.03.2012
comment
Ах, кажется, базы данных не было в списке ресурсов пакета копирования. Я добавил его, и теперь все выглядит нормально. Странно, что его не добавили автоматически. - person emachine; 14.03.2012
comment
@emachine :- Добавьте свой комментарий в качестве ответа на вопрос - person Jamal Zafar; 10.07.2013