Objective c sqlite fts不适用于应用程序的临时版本,但仅适用于从xcode启动的版本

Objective c sqlite fts不适用于应用程序的临时版本,但仅适用于从xcode启动的版本,objective-c,ios,ipad,sqlite,ios5,Objective C,Ios,Ipad,Sqlite,Ios5,我对sqlite有一个奇怪的问题,这让我发疯 我在我的应用程序中实现了一个sqlite数据库,当我通过xcode启动应用程序时,一切正常。在模拟器和我的ipad上。 但是,当我构建一个临时版本并在ipad上安装该临时版本时,应用程序在尝试启动时崩溃,因为它没有从sql数据库获取数据,因为数据库中没有数据。 在第一次启动时,应用程序应使用从xml文件获取的数据初始化数据库,然后仅通过sqlite数据库访问数据。 如果从xcode运行,效果很好,但如果从临时版本运行,效果就不好了 有人知道为什么会这

我对sqlite有一个奇怪的问题,这让我发疯

我在我的应用程序中实现了一个sqlite数据库,当我通过xcode启动应用程序时,一切正常。在模拟器和我的ipad上。 但是,当我构建一个临时版本并在ipad上安装该临时版本时,应用程序在尝试启动时崩溃,因为它没有从sql数据库获取数据,因为数据库中没有数据。 在第一次启动时,应用程序应使用从xml文件获取的数据初始化数据库,然后仅通过sqlite数据库访问数据。 如果从xcode运行,效果很好,但如果从临时版本运行,效果就不好了

有人知道为什么会这样,我如何解决这个问题吗?如果需要源代码,我会提供

数据库文件包含在捆绑包中,即使不包含,也会创建它

Thx提前, 特立独行的

现在我在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/katalogdane

我还发现,我的数据库是由sqlite打开的,因为下面的语句是正确的:

if(sqlite3_open([[AppState sharedInstance].s_databasePath UTF8String], &database) == SQLITE_OK)
*编辑** 在用iExplorer检查了我ipad上应用程序的文件系统后,我注意到这个表确实在那里,而且它本身也有内容。但由于我在我的应用程序中处理一个虚拟表,因为我需要全文搜索,所以如果数据库中不存在虚拟表,那么我想创建一个虚拟表,但这似乎以某种方式失败了。我会提供进一步的更新,如果我发现更多

**编辑***

所以,我想我找到了错误的地方,但不是什么原因

以下源代码正常执行,但仅在从我的ipad上的xcode运行时返回所需结果,而不是从我的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);

当通过xcode或从即席版本运行时,方法
fillSQLiteDataBaseTable
也会正常执行。唯一的区别是,对于ad-hoc版本,虚拟表的创建会失败,而应用程序不会告诉我。该应用程序继续运行,就好像什么也没发生一样,但当我在以后查看sql文件时,从即席版本运行时,那里没有虚拟表。虚拟表仅在从xCode运行时存在。

很好。。如果文件在资源包中,请不要在该文件上写入。。您应该首先复制应用程序文档目录中的空白数据库。。那么你应该在那个文件里写。。如果您签署了应用程序,apple sdk不允许更改nsbundle中的任何内容

以下是如何在documents目录中获取数据库的路径-

    NSString *documentsDir = [CommonFunctions documentsDirectory];

   databasePath = [[documentsDir stringByAppendingPathComponent:@"yourdatabase.sqlite"] retain];
   [self checkAndCreateDatabase];
//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];

}
获取此路径后,应检查数据库是否已存在(然后确定..),如果不存在,则使用以下功能将空白数据库从nsbundle复制到文档目录-

    NSString *documentsDir = [CommonFunctions documentsDirectory];

   databasePath = [[documentsDir stringByAppendingPathComponent:@"yourdatabase.sqlite"] retain];
   [self checkAndCreateDatabase];
//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];

}

如果您在这方面需要更多帮助,请发表评论。

我忘了在sqlite.c文件的开头添加以下行

#define SQLITE_ENABLE_FTS3
所以,当我从xcode运行我的版本时,基本上就是问题所在。我的捆绑包中使用了sqlite版本,它似乎支持fts3,因为我不知道为什么不需要使用该定义启用它

但我的iPad上的sqlite版本不支持fts。 这可能就是我的sqlite行为如此奇怪的原因


无论如何。现在它运行得非常平稳。

据说是我做的。我编辑了这篇文章来添加我为这个场景提供的函数。。。我正在使用.h或.m扩展名。。Xcode中没有.c文件。请告诉我。。谢谢