【问题标题】:SQLite database not saving on iOSSQLite 数据库未在 iOS 上保存
【发布时间】:2013-11-02 12:42:48
【问题描述】:

我正在更新数据库中的条目,该语句有效并且代码在数据库中更新。一旦应用程序关闭并重新打开,尽管数据库尚未保存。它似乎创建了一个临时数据库,然后实际上并没有保存到应用程序正在读取的数据库中。

这是我的代码:

-(void)updateDatabase:(int)Level andPlayer:(int)questionID{
    DataClass *obj=[DataClass getInstance];
    //NSFileManager *filemgr = [NSFileManager defaultManager];
    NSString* Database =[NSString stringWithFormat:@"levelProgress.db"];
    NSString* databaseP = [[[NSBundle          mainBundle]resourcePath]stringByAppendingPathComponent:Database];
databasePath = [[NSString alloc]initWithString:databaseP];

const char *dbpath = [databasePath UTF8String];
sqlite3_stmt *statement;

if (sqlite3_open(dbpath, &questionDB) == SQLITE_OK) {
    NSString *querySQL = [NSString stringWithFormat:@"UPDATE levelProgress SET completed_questions=completed_questions+1 WHERE level=%d", obj.levelSelected];
    const char *query_stmt = [querySQL UTF8String];
    sqlite3_prepare_v2(questionDB, query_stmt, -1, &statement, NULL);
    if(sqlite3_step(statement)==SQLITE_DONE){
        NSLog(@"update worked");
    }else{
        NSLog(@"did not work");
    }
    sqlite3_finalize(statement);
    sqlite3_close(questionDB);
    }
}

对此的任何帮助将不胜感激。

【问题讨论】:

  • 您无法更新只读文件。

标签: ios sql database sqlite


【解决方案1】:

将数据库文件databaseP 从应用程序包复制到用户文件夹,然后更新它。您不能更新应用程序包中的任何文件(它们始终是只读的)。

#define kDatabaseName (@"levelProgress.db")
- (void)checkAndCopyDatabaseIfNeeded
{
    if (!self.databasePath)
    {
        // Database should be present in user sandbox at root.
        self.databasePath = [NSString pathWithComponents:[NSArray arrayWithObjects:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject], kDatabaseName, nil]];
    }

    // Check if the file already copied/exists.
    NSFileManager *fileManager = [NSFileManager defaultManager];
    BOOL success = [fileManager fileExistsAtPath:self.databasePath];

    if(!success)
    {
        // Copy the file from app bundle to user sandbox (Files in app bundle can not be edited).

        NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:kDatabaseName];

#if DEBUG
        BOOL isCopied =
#endif
        [fileManager copyItemAtPath:databasePathFromApp toPath:self.databasePath error:nil];

        NSAssert(isCopied, @"Problem copying database file to user document folder");
    }
}

【讨论】:

  • 非常感谢,一旦文件在用户文档目录中,用户可以看到我放在那里的文件吗?如果可以,您能否阻止他们查看文件内容?
  • 此文件复制到应用沙箱的 Documents 目录中,相当安全。在未越狱的手机上,除了您的应用之外,其他任何人都无法访问此文件。在此处阅读官方文档(特别是“应用沙盒”部分)-developer.apple.com/library/ios/documentation/iphone/conceptual/…
  • 如果数据库不在库/应用程序支持中。将它放在文档目录中将使用户可以访问该文件。我的 Sqlite Db 是一个可写文件,但对用户没有任何意义。
  • 如果在 plist 中启用 'UIFileSharingEnabled',这将允许用户下载上述路径中的 SQLite 数据库。将其存储在“NSLibraryDirectory”位置可以避免将数据库暴露给用户。 developer.apple.com/library/ios/qa/qa1699/_index.html
【解决方案2】:

当数据库在包中时,它是只读的。写入时,您需要将数据库放在文档目录中!

在此处查看接受的答案:Use and Access Existing SQLite Database on iOS

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-30
    • 1970-01-01
    • 2016-08-15
    相关资源
    最近更新 更多