我正试图使用下面的代码将我的sqlite文件从应用捆绑包复制到documents目录中
-(id)init {
self = [super init];
if (self) {
//1。为UIManagedDocument 创建数据库文件的句柄
NSURL *docURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
docURL = [docURL URLByAppendingPathComponent:@"DefaultDatabase"];
self.document = [[UIManagedDocument alloc] initWithFileURL:docURL]; // URL of the location of document i.e. /documents directory
NSLog(@" URL document");
//set our document up for automatic migrations
if (self.document) {
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES],
NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES],
NSInferMappingModelAutomaticallyOption, nil];
self.document.persistentStoreOptions = options;
// Register for Notifications
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(objectsDidChange:) name:NSManagedObjectContextObjectsDidChangeNotification object:self.document.managedObjectContext];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidSave:) name:NSManagedObjectContextDidSaveNotification object:self.document.managedObjectContext];
} else {
NSLog(@"The UIManaged Document could not be initialized");
}
//2。在首次运行的情况下,检查持久存储文件是否不存在
if (!([[NSFileManager defaultManager] fileExistsAtPath:[self.document.fileURL path]])) {
NSLog(@" persistent file not found trying to copy from app bbundle");
NSString *docFileName = [UIManagedDocument persistentStoreName];
NSString *docFilePath = [[NSBundle mainBundle] pathForResource:docFileName ofType:@"sqlite"];
**NSLog(@" doc file path = %@", docFilePath);**
if (docFilePath) { // found the database file in app bundle
NSLog(@" found file in bundle");
//Production: Copy from app bundle.
NSError *error = nil;
NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *copyToPath = [searchPaths lastObject];
if([[NSFileManager defaultManager] copyItemAtPath:docFilePath toPath:copyToPath error:&error]){
NSLog(@"File successfully copied");
} else { // if could not locate the file
[[[UIAlertView alloc]initWithTitle:NSLocalizedString(@"error", nil) message: NSLocalizedString(@"failedcopydb", nil) delegate:nil cancelButtonTitle:NSLocalizedString(@"ok", nil) otherButtonTitles:nil] show];
NSLog(@"Error description-%@ n", [error localizedDescription]);
NSLog(@"Error reason-%@", [error localizedFailureReason]);
}
}
}
}
return self;
}
a) 我使用数据加载器应用程序创建了.sqlite文件,该应用程序使用UIManagedDcument将数据添加到核心数据中。.sqlite文件在documents目录中生成。
b) 我将*.sqlite文件添加到resources文件夹中,并将其添加到bundle中。如果我使用终端检查应用程序捆绑包。。我在bundle目录下看到了"持久存储"和<app name.momd>
文件。没有扩展名为.sqlite 的文件
c) 但在我上面的代码中,当我使用代码行检查应用程序捆绑包中是否存在文件时,它是成功的。因此文件存在于捆绑中
NSString *file = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:fileName];
d) 但当尝试复制时,它失败了,这意味着它无法在应用程序捆绑包中找到.sqlite文件(Cocca错误206)。
if([[NSFileManager defaultManager] copyItemAtPath:file toPath:copyToPath error:&error])
这和我在appbundle目录下没有看到.sqlite文件的事实是一致的,相反,我看到了一个持久存储和.mod文件。
那么我哪里错了?
编辑
这是我如何生成mydata.sqlite文件的解释。
我正在使用核心数据,并希望在首次向用户推出应用程序时提供一个预填充的数据库。所以我使用了一个数据加载器应用程序为我创建了.sqlite文件。我使用UIManagedDocument来处理核心数据。运行应用程序后,我看到在documents目录下创建了一个mydata.sqlite目录。目录结构如下
/用户///documents/mydata.sqlite/storeContent/persistenStore。
所以基本上,它不是创建一个文件,而是创建一个扩展名为.sqlite的目录,我看到了persistentStore文件。因此,当我尝试在目标构建阶段复制应用捆绑包下的资源时。。它添加了persistentStore而不是.sqlite文件。
无论描述什么,我的问题都是正确的,我应该在代码中以不同的方式处理它。如果是,我应该做些什么来处理数据存储。
我以为.sqlite是一个文件而不是一个目录。请引导
感谢
此行实际上并不检查文件是否存在:
NSString *file = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:fileName];
所做的只是在file
中构建路径。如果要检查它是否存在,则需要使用[NSFileManager fileExistsAtPath:]
。或者,您可以返回使用pathForResource:ofType:
,当它返回nil
时,这显然是正确的。
您似乎根本没有将文件复制到捆绑包中。这是Xcode项目配置的问题。
我阅读了UIManagedDocument上的苹果文档,以下是我在上出错的关键点
-
处理UIManagedDocument不正确。初始化托管文档时,需要指定文档位置的URL,而不是文档本身如果需要添加
-
您可以通过创建UIManagedDocument的子类来执行额外的自定义,即。重写persistentStoreName以自定义文档文件包内的持久存储文件的名称。
-
剪切和粘贴示例代码以获得处理数据文件的正确方法
使用initWithFileURL:;创建托管文档对象;如果需要,可以在使用文档的托管对象上下文之前对其进行配置。通常,您可以设置持久存储选项,如本例所示:
NSURL *docURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"FirstDocument"];
doc = [[UIManagedDocument alloc] initWithFileURL:docURL];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
doc.persistentStoreOptions = options;
**if ([[NSFileManager defaultManager] fileExistsAtPath:[docURL path]]**) {
[doc openWithCompletionHandler:^(BOOL success){
if (!success) {
// Handle the error.
}
}];
}
else {
[self addInitialData];
[doc saveToURL:docURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success){
if (!success) {
// Handle the error.
}
}];
}