如何在 iOS 中覆盖 SQLite 数据库
Posted
技术标签:
【中文标题】如何在 iOS 中覆盖 SQLite 数据库【英文标题】:How to overwrite a SQLite DB in iOS 【发布时间】:2013-04-29 17:12:52 【问题描述】:我在使用 SQLlite 数据库的地方创建了一个应用程序...如果需要,我会在应用程序第一次启动时使用以下方法将该数据库复制到 NSCaches 目录中:
- (void) copyDatabaseIfNeeded
//Using NSFileManager we can perform many file system operations.
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSString *dbPath = [self getDBPath];
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(!success)
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"datenbankSpeed"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success)
NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]);
- (NSString *) getDBPath
//Search for standard documents using NSSearchPathForDirectoriesInDomains
//First Param = Searching the documents directory
//Second Param = Searching the Users directory and not the System
//Expand any tildes and identify home directories.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths lastObject];
return [documentsDir stringByAppendingPathComponent:@"datenbankSpeed"];
我的问题是,如果我更改 Database- 文件并为我的客户创建一个新的应用程序文件,他们会在旧应用程序上安装新应用程序,但旧数据库仍在使用中,这将导致崩溃!
【问题讨论】:
【参考方案1】:我假设问题仅出在您更改数据库架构时。在 sqlite 数据库中创建一个版本表并添加一个列 schema_version
并使用代码中的值填充它。现在,每当您更改 sql 架构时,请更新代码中的 schema_version
编号。在copyDatabaseIfNeeded
中,检查您是否有现有的db 文件,打开它并阅读schema_version
。如果此版本与您当前的版本相同,那么您很好。否则,您需要迁移架构。您可能还希望将数据迁移到新架构中。
编辑:为了澄清 - 在copyDatabaseIfNeeded
,请执行以下操作:
int version = ... // read schema_version from db
if (version != kCurrentSchemaVersion)
// convert the schema into new version preserving data if required.
// this can be a multi-step process. Eg. if user directly upgrades to schema_version 3
// after schema_version 1, first you'll convert from 1->2, then 2->3.
您可能还想看看@Martin 在 cmets 中提到的PRAGMA user_version
。
【讨论】:
我认为你可以使用PRAGMA user_version
来达到这个目的。
感谢您的信息。您应该添加一个解释如何使用它的答案。
是的,这听起来不错,但是如何在我的 copyDatabaseIfNeeded 中准确地做到这一点?!你能举个例子吗?!
但是我可以用没有新列的数据库做什么?!有没有办法强制应用使用数据库?
是的,您需要发布另一个更新。在此更新中,确保您的数据库具有版本表。启动后,检查旧 db 文件是否存在,如果存在,check if it has the new column。如果没有,请通过执行ALTER TABLE ADD COLUMN
等相关命令将其转换为新的模式格式。希望这能澄清。以上是关于如何在 iOS 中覆盖 SQLite 数据库的主要内容,如果未能解决你的问题,请参考以下文章
如何获取存储在 iOS 持久性 sqlite 数据库中的值?
我们如何在Android中重用已经在IOS中创建的Sqlite文件[重复]