Ios 无法将sqlite文件从应用程序包复制到文档目录:getting(Cocoa错误260)
我正在尝试使用下面的代码将我的sqlite文件从应用程序包复制到documents目录Ios 无法将sqlite文件从应用程序包复制到文档目录:getting(Cocoa错误260),ios,sqlite,core-data,bundle,Ios,Sqlite,Core Data,Bundle,我正在尝试使用下面的代码将我的sqlite文件从应用程序包复制到documents目录 -(id)init { self = [super init]; if (self) { //一,。为UIManagedDocument创建数据库文件的句柄 NSURL *docURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainM
-(id)init {
self = [super init];
if (self) {
//一,。为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");
}
//二,。检查第一次运行时持久存储文件是否不存在
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) 我使用data loader应用程序创建了.sqlite文件,该应用程序使用UIManagedCoument向核心数据添加数据。.sqlite文件在documents目录中生成
b) 我将*.sqlite文件添加到resources文件夹并将其添加到bundle。如果我使用Terminal.检查应用程序捆绑包,我会在捆绑包目录下看到“persistent store”和
文件。没有扩展名为.sqlite的文件
c) 但在我上面的代码中,当我使用代码行检查应用程序包中是否存在文件时,它是成功的。所以文件存在于包中
NSString *file = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:fileName];
d) 但是当尝试复制时,它失败了,并给我(COCA错误206),这意味着它无法在应用程序包中找到.sqlite文件
if([[NSFileManager defaultManager] copyItemAtPath:file toPath:copyToPath error:&error])
这与我在appbundle目录下没有看到.sqlite文件这一事实是一致的,相反,我看到了一个持久存储和.momd文件
那么我错在哪里呢
编辑
这是我如何生成mydata.sqlite文件的说明
我正在使用核心数据,并希望在首次向用户启动应用程序时提供一个预发布的数据库。所以我使用了一个数据加载程序来为我创建.sqlite文件。我正在使用UIManagedDocument作为核心数据。运行应用程序后,我看到在documents目录下创建了一个mydata.sqlite目录。目录结构如下所示
/用户//…/documents/mydata.sqlite/storeContent/persistenStore
所以基本上,它不是创建一个文件,而是创建一个扩展名为.sqlite的目录,我看到了persistentStore文件。因此,当我尝试在构建阶段的目标中复制应用程序包下的资源时,它会添加persistentStore而不是.sqlite文件
我的问题无论描述什么都是正确的,我应该在代码中以不同的方式处理它。如果是,我应该做什么来处理数据存储
我以为.sqlite是一个文件而不是一个目录。请引导
谢谢这一行实际上并没有检查文件是否存在:
NSString *file = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:fileName];
所做的只是在文件中构建路径。如果要检查它是否存在,需要使用[NSFileManager fileExistsAtPath::
。或者您可以返回使用pathForResource:of type:
,当它返回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.
}
}];
}
.sqlite文件是目标的成员吗?是的,我在“构建阶段”选项卡中的“复制捆绑资源”下看到一个行项目,它的内容是“mydata.sqlite/StoreContent中的persistentStore..”。它实际上是一个文件夹/目录吗?是的,当我在终端中的/users//applications/iPhone simulator/Library/6.1/…下选中时,mydata.sqlite是一个目录。它有“StoreContent”目录,下面是“persistenStore”文件。在步骤c中,您应该执行[[NSBundle mainBundle]pathForResource:name of type:@“sqlite”]
。我猜它会返回零。我用如何生成预填充的.sqlite的信息编辑了我的问题。我自己也不清楚为什么.sqlite是一个目录而不是一个文件。我想事情就是这样。请让我知道如何处理.sqlite目录和持久存储文件。ThanksSQLite不是目录,这是您在最后有一个带有.sqlite
的目录的唯一原因,因为您就是这样创建它的。persistenStore
文件是SQLite文件,其余是您通过UIManagedDocument
创建的内容。谢谢。我明白了,我假设创建了一个文件。因此,在这种情况下,我可以为UIManagedDocument创建的persistentStore文件指定一个自定义名称,因为我需要访问该文件以将其添加到应用程序包中,然后才能将其用于我的主应用程序。非常感谢大家……这让我明白了。我认为你做不到。您为UIManagedDocument提供了总体文档名,它处理内部细节。如果您想控制SQLite文件的名称,请删除UIManagedDocument,并以老式的方式设置持久性堆栈。ok。我将使用UIManagedDocument生成的“persistentStore”文件添加到应用程序包中。现在,如何获取persistentStore文件的路径,因为NSString*docFilePath=[[NSBundle mainBundle]pathForResource:docFileName of Type:@“sqlite”]]返回null。你能看一下上面的代码吗?我已经更新了代码