设备上的核心数据未访问sqllite DB [英] Core Data on Device Not Accessing sqllite DB

查看:232
本文介绍了设备上的核心数据未访问sqllite DB的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

澄清'不访问'sqlite DB:上下文/存储不能检测设备上的.sqlite中的任何条目,尽管NSBundle具有.sqlite并且.sqlite的文件大小是正确的大小。在模拟器中,上下文/存储工作正常。



我很抱歉。我添加了一个模型版本到我的xcdatamodeld。我重置版本,让我的代码自动执行迁移,并重新填充我的数据库。



在iPhone模拟器,它的工作原理。但是,当运行一个设备时,它无法从数据库读取。



我输入代码来检测sqllite实际上是在设备上,还验证文件大小。正在从NSBundle正确复制SQLLite,以及指示有数据的文件大小。



不知何故,我的代码拒绝访问设备上的DB 。任何想法为什么这是?访问DB的代码没有改变 - 唯一改变的是datamodel。以下代码适用于升级前的设备。

  //返回应用程序的受管对象上下文。 
//如果上下文不存在,那么它将被创建并绑定到应用程序的持久存储协调器。
- (NSManagedObjectContext *)managedObjectContext
{
if(_managedObjectContext!= nil){
return _managedObjectContext;
}

NSPersistentStoreCoordinator * coordinator = [self persistentStoreCoordinator];
if(coordinator!= nil){
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return _managedObjectContext;
}

//返回应用程序的管理对象模型。
//如果模型不存在,则从应用程序的模型创建。
- (NSManagedObjectModel *)managedObjectModel
{
if(_managedObjectModel!= nil){
return _managedObjectModel;
}
NSURL * modelURL = [[NSBundle mainBundle] URLForResource:@sironawithExtension:@momd];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}

//返回应用程序的持久存储协调器。
//如果协调器不存在,则会创建它并将应用程序的存储添加到其中。
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if(_persistentStoreCoordinator!= nil){
return _persistentStoreCoordinator;
}

NSURL * storeURL = [[self applicationDocumentsDirectory] ​​URLByAppendingPathComponent:@sirona.sqlite];

NSString * databasePath = [NSBundle.mainBundle pathForResource:@sironaofType:@sqlite];
NSLog(@文件管理器:%@,[[NSFileManager defaultManager] contentOfDirectoryAtPath:[[NSBundle mainBundle] bundlePath] error:nil]
NSDictionary * attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:@sirona.sqliteerror:NULL];
UInt32 result = [attrs fileSize];
NSLog(@文件大小:%d,(unsigned int)result);
NSError * error = nil;

//重要部分从这里开始
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:@RepresentativeinManagedObjectContext:context]];
[request setIncludesSubentities:NO]; //省略子实体。默认值为YES(即包含子实体)

NSError * err;
NSUInteger count = [context countForFetchRequest:request error:& err];
NSLog(@Count:%lu,(unsigned long)count);

编辑:
不知道如何没有代码将它复制到设备。

 <$ c $ 

c> NSURL * storeURL = [[self applicationDocumentsDirectory] ​​URLByAppendingPathComponent:@sirona.sqlite];

if(![[NSFileManager defaultManager] fileExistsAtPath:[storeURL path]]){
NSURL * preloadURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@sironaofType: @sqlite]];
NSLog(@PreloadURL:%@,preloadURL);
NSError * err = nil;

if(![[NSFileManager defaultManager] copyItemAtURL:preloadURL toURL:storeURL error:& err]){
NSLog(@糟糕,可以复制预加载的数据);
}
}

NSError * error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];


解决方案

您必须将sqlite文件复制到hare读/写权限,在初始化CoreData上下文之前


Clarification on 'not accessing' sqlite DB: The context/store is not able to detect any entries in the .sqlite on devices only, despite the NSBundle having the .sqlite and the file size of the .sqlite being the correct size. In the simulator, the context/store works fine.

I'm pretty stumped on this. I added a model version to my xcdatamodeld. I reset the version, have my code to automatically do migrations, and repopulated my database.

On the iPhone simulator, it works. However, when running off a device, it fails to read from the database.

I've put in code to detect that the sqllite is actually on the device and also verify the file size. The SQLLite is being copied over correctly from the NSBundle, as well as the file size indicating there is data.

Somehow, my code is refusing to access the DB on the device. Any idea why this is? The code for accessing the DB has not changed - the only thing that changed was the datamodel. The code below was working for devices prior to the upgrade.

// 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;
}

How I'm accessing the DB through core data:

  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);

Edit: Not sure how this was working without the code to copy it to the device. But it seems to be working now.

Code to do this:

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]];

解决方案

You must copy your sqlite file on a folder where you hare read/write permissions, before initialize the CoreData context

这篇关于设备上的核心数据未访问sqllite DB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆