SQLite неправильно импортирует в iOS

Похоже, что когда я копирую файл .sqlite3 в iOS и использую FMDB для доступа к нему, база данных пуста. Я просто перетаскиваю его в Xcode. Когда я бегу:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"db.sqlite3"];
FMDatabase *db = [FMDatabase databaseWithPath:writableDBPath];

FMResultSet *results = [db executeQuery:@"SELECT * FROM tableName"];

results возвращает ноль. Глядя на [db lastErrorMessage], он говорит, что моя таблица не существует. Когда я открываю файл .sqlite в командной строке (тот, который хранится в симуляторе iPhone), я получаю пустую базу данных. Есть ли особый способ импорта базы данных SQLite в iOS? Если да, то как?


person darksky    schedule 07.04.2013    source источник


Ответы (2)


Я вижу две вероятные проблемы:

Во-первых, убедитесь, что файл .sqlite включен в цель вашего проекта. Выберите файл в файловом навигаторе; откройте панель «Утилиты» (значок правой панели в разделе с надписью «Вид») и найдите раздел под названием «Целевое членство». Если поле для желаемой цели (вероятно, у вас есть только одна) не отмечено, ваш файл базы данных не копируется в пакет.

Во-вторых, вы пытаетесь найти базу данных в каталоге документов. Однако вы должны вручную скопировать его из пакета в этот каталог, прежде чем сможете открыть его как файл с возможностью записи:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dbPath = [documentsDirectory stringByAppendingPathComponent:@"db.sqlite3"];

NSURL *dbURL = [NSURL fileURLWithPath:dbPath];

// copy a database from the bundle if not present
// on disk
NSFileManager *fm = [NSFileManager defaultManager];
if (![fm fileExistsAtPath:dbPath]) {
    NSURL *bundlePath = [[NSBundle mainBundle] URLForResource:@"db" withExtension:@"sqlite3"];
    NSError *error = nil;
    if (!bundlePath || ![fm copyItemAtURL:bundlePath toURL:dbURL error:&error]) {
        NSLog(@"error copying database from bundle: %@", error);
    }
}
person Seamus Campbell    schedule 07.04.2013
comment
Спасибо. [self applicationDocumentsDirectory] не найден. Я заменил его первыми тремя строками выше в моем вопросе. Затем я использовал NSString dbPath в качестве пути, и у меня все еще возникает та же проблема. Есть идеи, почему это так? Правильно ли я сделал, заменив ваш метод тремя строками выше? - person darksky; 07.04.2013
comment
Этот код скопирует БД из комплекта только в том случае, если в каталоге документов уже нет БД, поэтому убедитесь, что вы используете новую установку — удалите старую копию приложения со своего устройства или симулятора. Я думаю, что часть того, что здесь происходило, заключается в том, что -databaseWithPath: создавал новую БД, если не находил ее, что приводило к пустой сохраненной БД. - person Seamus Campbell; 07.04.2013

Я думаю, что вы можете также свой исходный код. Вам просто нужно открыть "db"

NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentDirectory = [paths objectAtIndex:0];
//NSString * documentDirectory = @"/Users/cefitdept/Documents/ImportDB/";

NSString * dbPath = [documentDirectory stringByAppendingPathComponent:@"ImportDB.sqlite"];
FMDatabase * db = [FMDatabase databaseWithPath:dbPath];
if (![db open]) {
    return;
}
FMResultSet * results = [db executeQuery:@"SELECT * FROM main"];
while ([results next]) {
    NSData * data = [results dataForColumn:@"engs"];
    NSString * string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
person YuAn Shaolin Maculelê Lai    schedule 13.02.2014