sqlite fts не работает в adhoc-версии приложения, но только в версии, запущенной из xcode - PullRequest
1 голос
/ 11 января 2012

У меня странная проблема с sqlite, которая сводит меня с ума.

Я внедрил базу данных sqlite в свое приложение, и когда я запускаю приложение через xcode, все работает нормально. В симуляторе так же как и на моем ipad. Но когда я создаю специальную версию и устанавливаю специальную версию на своем ipad, приложение вылетает при попытке запуска, потому что оно не получает данных из базы данных sql, потому что в базе данных нет данных. При первом запуске приложение должно инициализировать базу данных с данными, взятыми из XML-файла, а затем обращаться к данным исключительно через базу данных sqlite. Отлично работает, если запускается из xcode, но не работает из специальной версии.

Кто-нибудь знает, почему это так и как я могу решить эту проблему? Если понадобится исходный код, я его предоставлю.

Файл базы данных содержится в комплекте, и даже если этого не произойдет, он будет создан.

Спасибо заранее, Maverick1st

Прямо сейчас я делаю это в моем appDidFinishLaunchingWithOptions

NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
[AppState sharedInstance].s_databasePath = [documentsDir stringByAppendingPathComponent:[AppState sharedInstance].s_databaseName];



if ([self checkForSQLiteDataBaseFile])
{
    if (![self checkForSQLiteDataBaseTable]) {
        [self loadDataFromXMLIntoNSDictionary];
    }
}

-(BOOL) checkForSQLiteDataBaseFile
{
    BOOL ret = NO;
    // Check if the SQL database has already been saved to the users phone, if not then copy it over
// 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
// If the database already exists then return without doing anything
    if([fileManager fileExistsAtPath:[AppState sharedInstance].s_databasePath]) 
        {
            Log2(@"databasePath: %@", [AppState sharedInstance].s_databasePath);
            ret = YES;
            return ret;
        }

// 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:[AppState sharedInstance].s_databaseName];

    // Copy the database from the package to the users filesystem
    [fileManager copyItemAtPath:databasePathFromApp toPath:[AppState sharedInstance].s_databasePath error:nil];
    Log2(@"databasePath: %@", [AppState sharedInstance].s_databasePath);

    ret = YES;
    return ret;
}   

И это мой путь к документам: databasePath: / var / mobile / Applications / 0CE5F143-04AC-4E1C-9A94-2B253F86F854 / Documents / KatalogDaten

Я также узнал, что моя база данных открыта sqlite, для следующего утверждения верно:

if(sqlite3_open([[AppState sharedInstance].s_databasePath UTF8String], &database) == SQLITE_OK)

* EDIT ** проверив файловую систему приложения на моем ipad с помощью iExplorer, я заметил, что таблица действительно есть и имеет содержание само по себе. Но так как я работаю над виртуальной таблицей в своем приложении, потому что мне нужен полнотекстовый поиск, я хочу создать виртуальную таблицу, если ее нет в этой базе данных, и, похоже, что-то не получается. Я предоставлю дальнейшие обновления, если узнаю больше.

** Edit ***

Итак, я думаю, что я выяснил, где ошибка, но не в чем ее причина.

Следующий исходный код выполняется нормально, но возвращает желаемый результат только при запуске из xcode на моем ipad, а не при запуске из специальной версии на моем ipad.

if(sqlite3_open([[AppState sharedInstance].s_databasePath UTF8String], &database) == SQLITE_OK)
{
    NSLog(@"Database opened successfully!");
    const char *sqlQuery = [@"select DISTINCT tbl_name from sqlite_master where tbl_name = ?;" UTF8String]; 
    Log2(@"sqlquery for selecting distinct table: %s", sqlQuery);
    sqlite3_stmt *compiledQuery;
    if(sqlite3_prepare_v2(database, sqlQuery, -1, &compiledQuery, NULL) == SQLITE_OK) 
    {
        sqlite3_bind_text(compiledQuery, 1, [k_db_virtualTableName UTF8String], -1, SQLITE_TRANSIENT);

        if(sqlite3_step(compiledQuery)) 
        {
            // look if virtual table already exists
            if ((char *)sqlite3_column_text(compiledQuery, 0) == nil) 
            {
                NSLog(@"Create virtual table!");
                sqlite3_finalize(compiledQuery);

                sqlQuery = [[NSString stringWithFormat:@"CREATE VIRTUAL TABLE %@ USING FTS3 (%@);", k_db_virtualTableName, keyString] UTF8String];
                Log2(@"sqlQuery: %s", sqlQuery);        
                if(sqlite3_prepare_v2(database, sqlQuery, -1, &compiledQuery, NULL) == SQLITE_OK) 
                {   
                    NSLog(@"query for virtual table is ok!");
                    if(sqlite3_step(compiledQuery)) 
                    {
                        NSLog(@"query for virtual table was executed properly!");
                        sqlite3_finalize(compiledQuery);
                        [self fillSQLiteDataBaseTable: k_db_virtualTableName WithDataFromDict: [[[xmlDictionary objectForKey:@"UHRENTABELLE"] objectForKey:@"UHR"] mutableCopy]];
                    }
                    else
                    {
                        sqlite3_finalize(compiledQuery);
                    }
                }
            } 
            else
            {
                NSLog(@"Virtual Table already exists!!");
                sqlite3_finalize(compiledQuery);
            }
        }
    }
    else
    {
        NSLog(@"The following statement is not correct: %@", sqlQuery);
    }
}
sqlite3_close(database);

Метод fillSQLiteDataBaseTable также выполняется нормально при запуске через xcode или из специальной версии. Разница лишь в том, что в специальной версии создание виртуальной таблицы завершается неудачно, и приложение не сообщает мне об этом. Приложение просто продолжает, как будто ничего не произошло, но когда я заглядываю в файл sql впоследствии, там нет виртуальной таблицы при запуске из специальной версии. Виртуальная таблица существует только при запуске из xCode.

Ответы [ 2 ]

2 голосов
/ 11 января 2012

хорошо .. не пишите в файл, если этот файл находится в вашем комплекте ресурсов .. сначала вы должны скопировать пустую базу данных в директорию документов вашего приложения .. затем вы должны записать в этот файл .. apple sdk не делаетразрешить что-либо изменить в nsbundle, если вы подписали приложение.

Вот как вы можете получить путь к вашей базе данных в каталоге документов -

    NSString *documentsDir = [CommonFunctions documentsDirectory];

   databasePath = [[documentsDir stringByAppendingPathComponent:@"yourdatabase.sqlite"] retain];
   [self checkAndCreateDatabase];

После получения этого пути вы должны проверить, еслибаза данных уже существует (тогда хорошо ..), если нет, то используйте эту нижеприведенную функцию, чтобы скопировать вашу пустую базу данных из вашего nsbundle в каталог документов -

//check if database exists else copy
-(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:databasePath];

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

   // 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:@"yourdatabase.sqlite"];

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

}

оставьте комментарий, если вам нужна дополнительная помощь в этом.

0 голосов
/ 16 января 2012

Я забыл добавить следующую строку в заголовок моего файла sqlite.c

#define SQLITE_ENABLE_FTS3

Так что это была в основном проблема, когда я запускал свою версию из xcode.Была использована версия sqlite в моем комплекте, которая, по-видимому, поддерживает fts3 по какой-то причине, которую я не знаю без необходимости включать ее с этим определением.

Версия sqlite на моем iPad, хотя и не поддерживает fts.Так что это может быть причиной того, что мой sqlite вел себя так странно.

В любом случае.Теперь он работает идеально гладко.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...