如何在Xcode中使用已存在的数据库文件进行读写操作?

3
我对Xcode和sqlite有些陌生。现在我有一个名为“mydb.db”的数据库文件,其中已经有一些表和数据。我将它放在我的Mac文件夹中,并将其拖到Xcode项目的“Supporting Files”下。
这是我的代码,但我发现我只能从“mydb.db”读取数据,不能向其中插入数据!当我通过sqlite管理器执行我的代码后打开“mydb.db”,我找不到应该插入的数据!
谁能告诉我如何解决这个问题?非常感谢!
NSString *dbFilePath = [[NSBundle mainBundle] pathForResource:@"mydb" ofType:@"db"];
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:dbFilePath]

    [queue inDatabase:^(FMDatabase *db) {
        [db executeUpdate:@"INSERT INTO Focus VALUES (?,?,?)" withArgumentsInArray:@[@"100000000",@2,@2]];

    }];

请确保您只打开存储在“支持文件”文件夹下的 Xcode 项目中的更新数据库。 - Bhumeshwer katre
SQLite数据库必须被复制到一个可写位置。 - FluffulousChimp
SQLite数据库必须复制到可写位置,如何复制?哪个位置是可写位置?只需复制此文件并粘贴即可吗? - SomnusLee
是的,数据库必须复制到可写存储器中。如果您在此处搜索,很容易找到如何执行此操作的数百个示例。 - Hot Licks
2个回答

2
通过将SQLite数据库文件添加到Xcode的Supporting Files组中,您只是将该文件添加到应用程序的捆绑包中,以便在构建过程中它与所有其他资源一起打包。由于应用程序无法向其捆绑包中写入数据,因此您必须将SQLite数据库文件从捆绑包复制到可写位置,例如:
#define FORCE_RECOPY_DB NO

- (void)copyDatabaseIfNeeded {
    NSFileManager *fm = [[NSFileManager alloc] init];
    NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *destinationPath = [documentsPath stringByAppendingPathComponent:@"pte.sqlite"];

    void (^copyDb)(void) = ^(void){
        NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"pte" ofType:@"sqlite"];
        NSAssert1(sourcePath, @"source db does not exist at path %@",sourcePath);

        NSError *copyError = nil;
        if( ![fm copyItemAtPath:sourcePath toPath:destinationPath error:&copyError] ) {
            DDLogError(@"ERROR | db could not be copied: %@", copyError);
        }
    };
    if( FORCE_RECOPY_DB && [fm fileExistsAtPath:destinationPath] ) {
        [fm removeItemAtPath:destinationPath error:NULL];
        copyDb();
    }
    else if( ![fm fileExistsAtPath:destinationPath] ) {
        DDLogInfo(@"INFO | db file needs copying");
        copyDb();
    }
}

现在当您想要打开数据库时,请使用文档路径中的位置。
请注意,您将无法检查项目中的sqlite db文件并期望找到从代码中编写的更改。(因为您的代码现在将使用复制的sqlite文件。)

这将导致您的应用被拒绝,请使用其他路径:http://stackoverflow.com/questions/13896757/apps-must-follow-the-ios-data-storage-guidelines-or-they-will-be-rejected-in-app - Luqmaan

1

首先学习IOS的教程。

非常简单。

const char *sqlStatement = "insert into Userprofile (Userauth, Age, , Year) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";

然后使用sqlite3_prepare_v2语句来执行该sqlStatement。

嗨,我使用FMDB执行SQL语句,我认为FMDB类似于sqlite3_prepare_v2,对吧?我困惑的是,在代码执行后,mydb.db文件中没有正确的数据。 - SomnusLee
尝试使用 FMDatabase 替代 FMDatabaseQueue,并使用 databaseWithPath 替代 databaseQueueWithPath - Boggarapu
FMDatabase *database = [FMDatabase databaseWithPath:path]; [database open];[database beginTransaction];NSString *query = [NSString stringWithFormat:@"insert into person(rowid,fname,lname,address) values(null,'%@','%@','%@')",fname.text,lname.text,address.text]`;这对我很有效... - Boggarapu
啊哈,我找到答案了:链接。主捆绑包中的所有文件都是只读的。我需要将数据库复制到“文档”文件夹中。明白了!也谢谢你! - SomnusLee
是的,看起来你在我下面发布答案时找到了它。太好了! - FluffulousChimp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接