将sqlite导入coredata

时间:2011-02-15 10:09:12

标签: iphone sqlite core-data import

我之前已经将sqlite预先填充的dbs导入我的coredata项目,但现在我已经在3.2.5中创建了一个项目。 xcode,在AppDelegate中为nstring更改了nsurl,所以我继续使用它,但是现在我的sqlite没有导入到项目中,

如果我离开我的PersistentStoreCoordinator来创建新的db空白,它可以正常工作,

 NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"ChildCare_v02.sqlite"];

但是当我更改代码以导入预先填充的db(称为相同只是为了澄清)时,它会给我一个警告和崩溃,

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator_ != nil) {
return persistentStoreCoordinator_;
}
NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"ChildCare_v02.sqlite"]; //WARNING !! here
NSURL *storeUrl = [NSURL fileURLWithPath:storePath]; 
//NSURL *storeURL = [[self applicationDocumentsDirectory]    URLByAppendingPathComponent:@"ChildCare_v02.sqlite"]; //actual SDK style for blank db

// Put down default db if it doesn't already exist
    NSFileManager *fileManager = [NSFileManager defaultManager];
   if (![fileManager fileExistsAtPath:storePath]) {
    NSString *defaultStorePath = [[NSBundle mainBundle]  pathForResource:@"ChildCare_v02" ofType:@"sqlite"];
    if (defaultStorePath) {
        [fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
    }
    }
NSError *error = nil;
persistentStoreCoordinator_ = [[NSPersistentStoreCoordinator alloc]  initWithManagedObjectModel:[self managedObjectModel]];
if (![persistentStoreCoordinator_ addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) {


NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
    }    
    return persistentStoreCoordinator_;
    }

这是控制台中的崩溃日志

-[NSURL stringByAppendingPathComponent:]: unrecognized selector sent to instance  0x5b40e50
 2011-02-15 21:06:59.245 Staff_02c[469:207] *** Terminating app due to uncaught  exception 'NSInvalidArgumentException', reason: '-[NSURL stringByAppendingPathComponent:]:     unrecognized selector sent to instance 0x5b40e50'

如何解决这个问题? 就在我艰难的时候,我获得了核心数据!!面团!!

5 个答案:

答案 0 :(得分:5)

apple改变了在核心数据模板中返回应用程序字典的辅助方法。

您依赖此版本:

- (NSString *)applicationDocumentsDirectory {
    return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}

但苹果将其更改为此版本

- (NSURL *)applicationDocumentsDirectory {
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

要修复它,只需更改它。

NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"ChildCare_v02.sqlite"]; //WARNING !! here
NSURL *storeUrl = [NSURL fileURLWithPath:storePath]; 
//NSURL *storeURL = [[self applicationDocumentsDirectory]    URLByAppendingPathComponent:@"ChildCare_v02.sqlite"]; //actual SDK style for blank db

到这个

//NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"ChildCare_v02.sqlite"]; //WARNING !! here
//NSURL *storeUrl = [NSURL fileURLWithPath:storePath]; 
NSURL *storeUrl = [[self applicationDocumentsDirectory]    URLByAppendingPathComponent:@"ChildCare_v02.sqlite"]; //actual SDK style for blank db
抱歉,但是omfg

答案 1 :(得分:4)

感谢Ishu,你通过指向NSArray的方式给了我很多帮助!!!

这是我最终通过启蒙的解决方案!

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

if (persistentStoreCoordinator_ != nil) {
    return persistentStoreCoordinator_;
}



NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"ChildCare_v02.sqlite"];

NSString *storePath = [[NSBundle mainBundle] pathForResource:@"ChildCare_v02" ofType:@"sqlite"];


NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"ChildCare_v02.sqlite"]; //este es el que sirve!!! CREE ESTE

NSLog(@"store URL %@", storeURL);

    // Put down default db if it doesn't already exist
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:writableDBPath]) {
    NSLog(@"proceda aqui");
    NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"ChildCare_v02" ofType:@"sqlite"];
    NSLog(@"no existe todavia");
    NSLog(@"defalultStorePath %@", defaultStorePath);


    if (defaultStorePath) {
      [fileManager copyItemAtPath:defaultStorePath toPath:writableDBPath error:NULL];
        NSLog(@"storePath= %@", storePath);
    }
}    

NSError *error = nil;
persistentStoreCoordinator_ = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![persistentStoreCoordinator_ addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {

NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
    }    

   return persistentStoreCoordinator_;
    }

希望它能帮助像我一样想要将预先填充的sqlite导入到coredata db的一些菜鸟, 注意,首先需要创建空白db,保持结构然后填充(我使用SQLite数据库浏览器将CSV列导入我的sqlite)

SS9

答案 2 :(得分:2)

您根本不需要使用NSString路径,它们都可以使用NSURL方法完成。

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Database.sqlite"];

// If the database doesn't exist copy in the default one
if (![storeURL checkResourceIsReachableAndReturnError:NULL])
{
    NSURL *defaultStoreURL = [[NSBundle mainBundle] URLForResource:@"Database" withExtension:@"sqlite"];

    if ([defaultStoreURL checkResourceIsReachableAndReturnError:NULL])
    {
        NSFileManager *fileManager = [NSFileManager defaultManager];
        [fileManager copyItemAtURL:defaultStoreURL toURL:storeURL error:NULL];
    }
}

答案 3 :(得分:1)

stringByAppendingPathComponent此方法是NSString类的实例方法。因此您无法在NSURL上访问此方法。

所以校正改变这一行

NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"ChildCare_v02.sqlite"];

通过此代码

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"ChildCare_v02.sqlite"];

答案 4 :(得分:0)

崩溃与核心数据无关。

看起来你正在调用一个不存在的方法。

在NSURL中,方法是“URLByAppendingPathComponent”。

如果你想要stringByAppendingPathComponent,那就是NSString。

你很可能在构建期间对此发出警告。