【问题标题】:import if database not exist in iOS sqlite如果 iOS sqlite 中不存在数据库,则导入
【发布时间】:2014-07-17 03:19:03
【问题描述】:

我的问题是它总是在渲染我的应用程序时从资源文件中导入 sqlite 数据库(它已经有很多设置数据)。第一次渲染我的应用程序时,它从资源文件中导入 sqlite 数据库,并将一些数据插入到表中。但是第二次再次渲染,它再次导入并丢失了我插入的记录。以下是我的编码。

如果数据库存在,我想要的不需要导入。

static NaWinDatabase *_database;

+ (NaWinDatabase*)database {
    if (_database == nil) {
        _database = [[NaWinDatabase alloc] init];
    }
    return _database;
}

- (id)init {
    if ((self = [super init])) {
        NSString *sqLiteDb = [[NSBundle mainBundle] pathForResource:@"nawin" ofType:@"sqlite3"];

        if (sqlite3_open([sqLiteDb UTF8String], &_database) != SQLITE_OK) {
            NSLog(@"Failed to open database!");
        }
    }
    return self;
}

【问题讨论】:

    标签: ios sqlite


    【解决方案1】:

    copyDatabaseIfNeeded如果不是第一次复制,会将你的资源数据库复制到应用程序目录文件夹中

    + (void) copyDatabaseIfNeeded {
    
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSError *error;
        NSString *dbPath = [self getDBPath];
        BOOL success = [fileManager fileExistsAtPath:dbPath];
        if(!success) {
    
            NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"db.sqlite"];
            success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
    
            if (!success)
                NSAssert1(0, @"Failed to create writable database file with message \"%@\".", [error localizedDescription]);
        }
    }
    

    //将数据库保存在应用程序文档目录中的路径

     + (NSString *) getDBPath {
            NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
            NSString *documentsDir = [paths objectAtIndex:0];
            return [documentsDir stringByAppendingPathComponent:@"db.sqlite"];
        }
    

    【讨论】:

      【解决方案2】:

      只需在应用启动时检查 SQLite DB 是否存在,如果不存在则导入它,如果存在则不要导入。 SQLite DB 只是一个文件。

      【讨论】:

      • 你能给我举个例子吗?
      【解决方案3】:

      无论文件是否存在,sqlite3 的sqlite3_open 都会成功。

      我假设您的数据库是从 SQL 创建的。如果是这样并且您想查看数据库是否已设置,您可以对数据库连接执行pragma schema_version; 查询。如果它返回 0,则还没有表。任何其他值,并且您已经创建了表。

      确保你的表创建和记录插入是原子的,你应该没有更多的麻烦。

      【讨论】:

      【解决方案4】:

      我最近没有在 iOS 上使用 sqlite,但我记得必须在文档目录中打开数据库。我相信出于安全原因,无法修改主捆绑包。本质上,您的数据库是只读的。

      我会这样做:

          NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
          NSString *dbPath = [docsPath stringByAppendingPathComponent:name];
          fmdb = [FMDatabase databaseWithPath:dbPath];
          [fmdb open];
      

      【讨论】:

        【解决方案5】:

        试试这个可能会帮上忙...它工作正常

            - (void)copyDatabaseIfNeeded {
            // First, test for existence.
               BOOL success;
               NSFileManager *fileManager      =   [NSFileManager defaultManager];
               NSError *error;
            NSArray *paths                  =   NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
            NSString *documentsDirectory    =   [paths objectAtIndex:0];
            writableDBPath                  =   [documentsDirectory stringByAppendingPathComponent:@"carDatabase.sqlite"];
        
            success                         =   [fileManager fileExistsAtPath:writableDBPath];
            if (success)
                return;
            // The writable database does not exist, so copy the default to the appropriate location.
            NSString *defaultDBPath         =   [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"carDatabase.sqlite"];
            success                         =   [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
            NSLog(@"Result For Database path %c",success);
            if (!success) {
                NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]);
            }
            NSLog(@"Result For Database path %c",success);
        }
        
        //Get DataBase Path
        - (NSString *) getDBPath {
            NSString *sqLiteDb = writableDBPath ; // [[NSBundle mainBundle] pathForResource:@"liveonmap_iphone" ofType:@"sqlite"];
        
            return sqLiteDb;
        }
        

        干杯...

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-10-14
          • 1970-01-01
          • 2020-06-17
          • 2015-03-31
          • 2011-01-13
          • 1970-01-01
          • 2016-11-19
          相关资源
          最近更新 更多