我正在(最终)将我的应用程序加载到iPhone设备上进行测试。到目前为止,我只在模拟器中测试了App。该应用程序是以数据为中心的,并使用SQLite数据库。我创建了一个合适的SQLite数据库,其中包含我在模拟器中使用的样本数据。如何将此.sqlite3文件复制到实际的iPhone?
使用模拟器很容易,因为我可以将.sqlite3文件复制到〜/ Library / Application Support / iPhone Simulator / User / Applications / {UUID} / Documents 文件夹中,但是我无法弄清楚如何将它放到实际的iPhone设备上的相同位置。在手机上重新创建数据库并不是一个真正的选择,因为我已经完成了在Mac上创建数据库的所有硬码。
答案 0 :(得分:11)
正如Alex所说,您必须将数据库文件作为资源添加到项目中。这将指示Xcode将您的数据库文件捆绑在.app中。然而,该文件是只读的,由您将其复制到您的应用程序文档文件夹(在设备或模拟器上,同样的东西),它基本上可写。
下面是我用于此类事情的代码。关于此代码的好处是,只要您更改.app中捆绑的“主”副本,它就会自动刷新应用程序文档文件夹中的可写副本。使用'pathLocal'打开(可写)数据库......
当操作成功时(无论是否需要复制),下面的函数返回YES。你可以随意改变它:)
NSString *pathLocal, *pathBundle;
// Automatically copy DB from .app bundle to device document folder if needed
- (BOOL)automaticallyCopyDatabase {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
pathLocal = [documentsDir stringByAppendingPathComponent:@"mydb.sqlite"];
pathBundle = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"mydb.sqlite"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSDictionary *localAttr = [fileManager fileAttributesAtPath:pathLocal traverseLink:YES];
BOOL needsCopy = NO;
if (localAttr == nil) {
needsCopy = YES;
} else {
NSDate *localDate;
NSDate *appDBDate;
if (localDate = [localAttr objectForKey:NSFileModificationDate]) {
NSDictionary *appDBAttr = [fileManager fileAttributesAtPath:pathBundle traverseLink:YES];
appDBDate = [appDBAttr objectForKey:NSFileModificationDate];
needsCopy = [appDBDate compare:localDate] == NSOrderedDescending;
} else {
needsCopy = YES;
}
}
if (needsCopy) {
NSError *error;
BOOL success;
if (localAttr != nil) {
success = [fileManager removeItemAtPath:pathLocal error:&error];
}
success = [fileManager copyItemAtPath:pathBundle toPath:pathLocal error:&error];
return success;
}
return YES;
}
答案 1 :(得分:6)
为什么不将它添加到您的应用程序包中?右键单击Xcode中项目窗口中的Resources
文件夹,然后选择Add
> Existing Files...
添加您的sqlite数据库。
然后,您将从应用程序包中加载文件:
NSString *databasePath = [[NSBundle mainBundle] pathForResource:@"mySQLiteDatabaseFile" ofType:@"sqlite3"];
NSData *databaseData = [NSData dataWithContentsOfFile:databasePath];
// ...
答案 2 :(得分:0)
这里我是如何创建一个名为DBManagement的类的 并在m文件中实现这些方法。也将此行放在@implementation line
上面的实现文件中static sqlite3 * CHManagement = nil;
-(NSString *) getDBPath
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *MyDatabasePath = [documentsDirectory stringByAppendingString:@"/CHManagement.sqlite"];
return MyDatabasePath;
}
-(void) checkDataBase
{
NSLog(@"CheckDatabase Called");
NSFileManager *fileManager=[NSFileManager defaultManager];
NSError *error=[[[NSError alloc]init] autorelease];
NSString *dbPath = [self getDBPath];
BOOL success=[fileManager fileExistsAtPath:dbPath];
if(!success)
{
NSString *defaultDBPath=nil;
defaultDBPath=[[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent:@"CHManagement.sqlite"];
success=[fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if(!success)
{
NSAssert1(0,@"failed to create database with message '%@'.",[error localizedDescription]);
}
}
else
{
sqlite3 *MyDatabase;
NSInteger VersionNumber=0;
sqlite3_stmt *CompiledStatement=nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *MyDatabasePath = [documentsDirectory stringByAppendingString:@"/CHManagement.sqlite"];
if(sqlite3_open([MyDatabasePath UTF8String],&MyDatabase) == SQLITE_OK)
{
sqlite3_prepare_v2(MyDatabase, "select appVersionNo from VersionInfo", -1, &CompiledStatement, NULL);
while(sqlite3_step(CompiledStatement) == SQLITE_ROW)
{
VersionNumber=sqlite3_column_int(CompiledStatement,0);
}
sqlite3_reset(CompiledStatement);
sqlite3_finalize(CompiledStatement);
sqlite3_close(MyDatabase);
}
if (VersionNumber!=1)
{
[self deleteDatabase];
NSString *defaultDBPath=[[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent:@"CHManagement.sqlite"];
success=[fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if(!success)
{
NSAssert1(0,@"failed to create database with message '%@'.",[error localizedDescription]);
}
}
}
}
- (void)deleteDatabase
{
NSLog(@"Delete Database Called");
NSError **error=nil;
NSFileManager *FileManager = [NSFileManager defaultManager];
NSString *databasepath = [self getDBPath];
BOOL success = [FileManager fileExistsAtPath:databasepath];
if(success) {
[FileManager removeItemAtPath:databasepath error:error];
}
}
使用这些方法,您可以轻松地将数据库加载到应用程序的iphone文档文件夹中。
抱歉格式化。和appVersionNo是tableCalled versionInfo中的一个字段,默认值为1