Ios 设备上的核心数据未访问sqllite数据库
关于“不访问”sqlite DB的说明:尽管NSBundle的.sqlite和.sqlite文件大小正确,但上下文/存储区仅在设备上无法检测到.sqlite中的任何条目。在模拟器中,上下文/存储工作正常 这件事让我很难堪。我在xcdatamodeld中添加了一个模型版本。我重置了版本,让代码自动执行迁移,并重新填充了数据库 在iPhone模拟器上,它可以工作。但是,当运行设备时,它无法从数据库中读取数据 我已经输入代码来检测sqllite是否确实在设备上,并验证文件大小。正在从NSBundle中正确复制SQLLite,以及表示存在数据的文件大小 不知何故,我的代码拒绝访问设备上的数据库。知道为什么吗?访问数据库的代码没有改变——唯一改变的是数据模型。以下代码适用于升级之前的设备Ios 设备上的核心数据未访问sqllite数据库,ios,core-data,Ios,Core Data,关于“不访问”sqlite DB的说明:尽管NSBundle的.sqlite和.sqlite文件大小正确,但上下文/存储区仅在设备上无法检测到.sqlite中的任何条目。在模拟器中,上下文/存储工作正常 这件事让我很难堪。我在xcdatamodeld中添加了一个模型版本。我重置了版本,让代码自动执行迁移,并重新填充了数据库 在iPhone模拟器上,它可以工作。但是,当运行设备时,它无法从数据库中读取数据 我已经输入代码来检测sqllite是否确实在设备上,并验证文件大小。正在从NSBundle中
// Returns the managed object context for the application.
// If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
- (NSManagedObjectContext *)managedObjectContext
{
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return _managedObjectContext;
}
// Returns the managed object model for the application.
// If the model doesn't already exist, it is created from the application's model.
- (NSManagedObjectModel *)managedObjectModel
{
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"sirona" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
// Returns the persistent store coordinator for the application.
// If the coordinator doesn't already exist, it is created and the application's store added to it.
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"sirona.sqlite"];
NSString *databasePath = [NSBundle.mainBundle pathForResource:@"sirona" ofType:@"sqlite"];
NSLog(@"File manager: %@", [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[[NSBundle mainBundle] bundlePath] error:nil]);
NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath: @"sirona.sqlite" error: NULL];
UInt32 result = [attrs fileSize];
NSLog(@"File size: %d", (unsigned int)result);
NSError *error = nil;
// important part starts here
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES],NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
nil];
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
我如何通过核心数据访问数据库:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Representative" inManagedObjectContext:context]];
[request setIncludesSubentities:NO]; //Omit subentities. Default is YES (i.e. include subentities)
NSError *err;
NSUInteger count = [context countForFetchRequest:request error:&err];
NSLog(@"Count: %lu", (unsigned long)count);
编辑:
如果没有将其复制到设备的代码,则无法确定这是如何工作的。但它现在似乎起作用了
执行此操作的代码:
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"sirona.sqlite"];
if (![[NSFileManager defaultManager] fileExistsAtPath:[storeURL path]]) {
NSURL *preloadURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"sirona" ofType:@"sqlite"]];
NSLog(@"PreloadURL: %@", preloadURL);
NSError* err = nil;
if (![[NSFileManager defaultManager] copyItemAtURL:preloadURL toURL:storeURL error:&err]) {
NSLog(@"Oops, could copy preloaded data");
}
}
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
在初始化CoreData上下文之前,必须将sqlite文件复制到具有读/写权限的文件夹中哪个部分实际失败?那些
NSLog
s打印的内容是否与您预期的有所不同?“拒绝访问”是相当含糊的。对不起,我会更新一点问题。失败的部分实际上是从.sqlite获取数据——具体来说,它只在设备上显示我在DB中搜索的任何条目的0个结果(相同的代码适用于模拟器)。我没有得到任何崩溃,NSLogs正在验证.sqlite是否存在(并且其中有数据)。我正在检查以确保.sqlite在存档时被捆绑。我没有看到[\u persistentStoreCoordinator addPersistentStoreWithType:…]
在storeURL
处的sqlite文件附加到存储协调器的代码中调用!(但是如果代码真的丢失了,那么它也会在模拟器上失败:-)啊!抱歉,Martin,格式化时,我不小心从复制和粘贴中删除了它。不过眼光不错!将其添加到上面的复制粘贴中-虽然它在代码中:)。@LyricalPanda:请始终尝试复制/粘贴真实完整的代码。您在一个位置有\u persistentstorecordinator
,在另一个位置有\u persistentstorecordinator
。这使得其他人理解代码并发现问题变得不必要复杂!在managedObjectContext中,我在alloc之前创建协调器并初始化ObjectContext。因此,在创建上下文之前,似乎正在复制sqlite文件。如何检查正在写入的文件夹是否具有读/写权限?查看您的代码,您仍然将该文件引用到MainBundle中。。。因此,您的sqlite文件是一个只读文件,您应该手动将该文件复制到NSHomeDirectory()/Ducuments。。。或者类似的