Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c FMDB-无法从Cocoa修改数据库_Objective C_Cocoa_Fmdb - Fatal编程技术网

Objective c FMDB-无法从Cocoa修改数据库

Objective c FMDB-无法从Cocoa修改数据库,objective-c,cocoa,fmdb,Objective C,Cocoa,Fmdb,我正在开发一个Cocoa应用程序,该应用程序使用FMDB与本地SQLite数据库进行通信。我遇到了一个问题,我无法在DB上执行任何插入或更新操作。Select查询运行得非常好,所以我假设我的db连接设置是正确的 我的代码的结构基本上是这样的: FMDatabase* db=[FMDatabase databaseWithPath:[[NSBundle mainBundle] pathForResource:@"DBName" ofType:@"sqlite"]]; if(![db open])

我正在开发一个Cocoa应用程序,该应用程序使用FMDB与本地SQLite数据库进行通信。我遇到了一个问题,我无法在DB上执行任何插入或更新操作。Select查询运行得非常好,所以我假设我的db连接设置是正确的

我的代码的结构基本上是这样的:

FMDatabase* db=[FMDatabase databaseWithPath:[[NSBundle mainBundle] pathForResource:@"DBName" ofType:@"sqlite"]];

if(![db open])
{
  NSLog(@"Could not open db.");
}

db.traceExecution=YES;
[db beginTransation];
[db ExecuteUpdate:"INSERT INTO test (title) VALUES(?)", [NSNumber numberWithInt]:2],nil];
[db commit];
[db close];
执行期间未引发异常或警告,有关db.traceExecution的控制台输出如下所示:

<FMDatabase: 0x100511fd0> executeUpdate: BEGIN EXCLUSIVE TRANSACTION;
<FMDatabase: 0x100511fd0> executeUpdate: INSERT INTO test (title) VALUES(?);
obj: 2
<FMDatabase: 0x100511fd0> executeUpdate: COMMIT TRANSACTION;
executeUpdate:开始独占事务;
executeUpdate:插入测试(标题)值(?);
obj:2
executeUpdate:提交事务;
测试数据库只是一个INT类型的单列表

一切看起来都很好,只是数据库文件根本没有更新。我真的很困惑,因为Select查询工作得非常好。我检查了数据库的路径,它指向正确的路径。首先,我怀疑这是由文件权限引起的,但即使我允许每个人都能读/写,问题仍然是一样的


我已经被这个问题困扰了好几个小时,找不到合适的解决办法。有人能解释一下吗?谢谢

捆绑包中的数据库是只读的。如果定义的目标文件夹中不存在该文件,则应将其从捆绑包复制到库或文档文件夹,然后连接到该文件夹。这意味着它将在第一次使用该路径时进行复制

这里有一个函数,可以通过将数据库从捆绑包复制到目标来“准备”数据库。它会将其复制到库中(从我的iOS应用程序),但您可以在任何地方复制。在我的例子中,是contacts.db

我从一开始就调用了这个方法

- (BOOL)ensureDatabasePrepared: (NSError **)error
{
    // already prepared
    if ((_dbPath != nil) &&
        ([[NSFileManager defaultManager] fileExistsAtPath:_dbPath]))
    {
        return YES;
    }

    // db in main bundle - cant edit.  copy to library if !exist
    NSString *dbTemplatePath = [[NSBundle mainBundle] pathForResource:@"contacts" ofType:@"db"];
    NSLog(@"%@", dbTemplatePath);

    NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
    _dbPath = [libraryPath stringByAppendingPathComponent:@"contacts.db"];

    NSLog(@"dbPath: %@", _dbPath);

    // copy db from template to library
    if (![[NSFileManager defaultManager] fileExistsAtPath:_dbPath])
    {
        NSLog(@"db not exists");
        NSError *error = nil;
        if (![[NSFileManager defaultManager] copyItemAtPath:dbTemplatePath toPath:_dbPath error:&error])
        {
            return NO;
        }

        NSLog(@"copied");
    }    

    return YES;    
}

捆绑包中的数据库是只读的。如果定义的目标文件夹中不存在该文件,则应将其从捆绑包复制到库或文档文件夹,然后连接到该文件夹。这意味着它将在第一次使用该路径时进行复制

这里有一个函数,可以通过将数据库从捆绑包复制到目标来“准备”数据库。它会将其复制到库中(从我的iOS应用程序),但您可以在任何地方复制。在我的例子中,是contacts.db

我从一开始就调用了这个方法

- (BOOL)ensureDatabasePrepared: (NSError **)error
{
    // already prepared
    if ((_dbPath != nil) &&
        ([[NSFileManager defaultManager] fileExistsAtPath:_dbPath]))
    {
        return YES;
    }

    // db in main bundle - cant edit.  copy to library if !exist
    NSString *dbTemplatePath = [[NSBundle mainBundle] pathForResource:@"contacts" ofType:@"db"];
    NSLog(@"%@", dbTemplatePath);

    NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
    _dbPath = [libraryPath stringByAppendingPathComponent:@"contacts.db"];

    NSLog(@"dbPath: %@", _dbPath);

    // copy db from template to library
    if (![[NSFileManager defaultManager] fileExistsAtPath:_dbPath])
    {
        NSLog(@"db not exists");
        NSError *error = nil;
        if (![[NSFileManager defaultManager] copyItemAtPath:dbTemplatePath toPath:_dbPath error:&error])
        {
            return NO;
        }

        NSLog(@"copied");
    }    

    return YES;    
}

谢谢你的建议。我试过你提到的方法。在我的情况下,它总是返回“//已经准备好”。因此,它不会到达下一步,即将db文件复制到库中。只需解决它。您是对的,我对NSBundle中的db文件没有写访问权。但是,至少在我的例子中,将文件复制到库路径并没有解决权限问题。将其复制到~/Documents/文件夹解决了我的问题。谢谢您的建议。我试过你提到的方法。在我的情况下,它总是返回“//已经准备好”。因此,它不会到达下一步,即将db文件复制到库中。只需解决它。您是对的,我对NSBundle中的db文件没有写访问权。但是,至少在我的例子中,将文件复制到库路径并没有解决权限问题。把它复制到~/Documents/folder解决了我的问题。布莱恩是对的。解决方案:将db文件复制到项目文件夹之外。在我的例子中,放入~/Documents/文件夹解决了我的问题。是的。对不起,我忘了把你的回答标记为已接受。再次感谢!布莱恩是对的。解决方案:将db文件复制到项目文件夹之外。在我的例子中,放入~/Documents/文件夹解决了我的问题。是的。对不起,我忘了把你的回答标记为已接受。再次感谢!