我的应用程序不会更新新版本的只读Core Data sqlite数据库

时间:2012-07-14 20:27:02

标签: objective-c core-data

====我的解决方案==== 我通过将数据库存储在主捆绑包中来解决这个问题,并在每次更新应用程序时更改数据库的名称。

我确实考虑过刷新模型等,但并没有真正按照我的意愿去工作。

How i solved this problem

====原始问题====

我很抱歉我以不同的格式提出过这个问题,之前我无法解决,可能是因为我问的问题。我确实删除了旧问题。

我有一个使用Core Data sqlite只读/数据库的应用程序,我正在尝试使用数据库中的新版本(记录中的版本#inbeded)更新应用程序。无论我做什么,除了手动清理目标和重置模拟器,它仍然读取旧数据库。我需要能够通过代码执行此操作。

在初始设计期间,我发布了以下内容以尝试解决同样的问题:The initial design。现在数据库太大了,首次启动时需要花费大量时间来构建它。

过程:

  

A。)我将新数据库版本添加到XCODE项目中,并通过Xcode手动将其添加到捆绑包中

     

B.)我检查使用的数据库版本

     

C。)如果有新数据库,我删除文档目录中的旧数据库,然后将新版本从主包复制到文档目录

     

D。)在附加的代码中我也删除了Cache目录并重新创建它,我发现了一些帖子,指出缓存可能是原因。这仅用于测试,但仍包含在代码中

尽管如此,应用程序仍然无法访问更新的sqlite数据库。

我在主捆绑中加载了一个新的数据库版本,我有一个版本参数“EEEEEE”,当我读取当前数据库时它有“SSSSSS”参数,所以应该更新数据库。

我一直在处理这个问题,并在网上搜索了很长时间,我只是无法理解错误。为什么它不访问文档目录中的新数据库。

我很感激所有帮助。我希望代码看起来并不奇怪,因为我已经包含了我用来试图了解正在发生的事情的NSLog。

跟踪(NSLog):

applicationDidFinishLaunchingWithOptions

readQuestion

persistentStoreCoordinator

==>PARAMETER is EEEEEE (000000)

==> Update needed


=======================
====BEFORE REPLACE====
===>CURRENT: SSSSSS: 999999
=======================
replaceDatabase function
=======================

=======================
     DELETE CACHE
=======================

Remove successful

=======================
   CREATE NEW CACHE
=======================

===============================
REMOVE sqlite FROM DOCUMENT DIR
===============================

removeItemAtPath:dbDocumentsPath: /Users/xxxxxx/Library/Application Support/iPhone Simulator/5.1/Applications/912962FC-933E-4305-971B-FF094BBD9051/Documents/database.sqlite

=====================================
CHECK IF sqlite EXIST IN DOCUMENT DIR
=====================================

===FILE DOES NOT EXIST===

========================================
MOVE sqlite FROM BUNDLE TO DOCUMENTS DIR
========================================

==>copyItemAtPath:dbBundlePath<<
====================================
CHECK IF sqlite EXIST IN DOCUMENT DIR
=====================================

===FILE EXIST===

readQuestion

=======================
=====AFTER REPLACE=====
=======================
Updated database is SSSSSS

========>STOP<========= 

以下是delegate.m中的代码,“didFinishLaunchingWithOptions”:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
NSLog(@"applicationDidFinishLaunchingWithOptions");
NSLog(@" ");

[window addSubview:navigationController.view];
[window makeKeyAndVisible];

//==CHECK IF DATABASE NEEDS TO BE UPDATED==//
//====Check if database needs to be refreshed====//


AccessQuestionsDB *refreshDB_function = [AccessQuestionsDB new];
qArray = [refreshDB_function readQuestion: 999999];
NSLog(@" ");

//Tell what language DB 
if ([k_DBVERSION isEqualToString:@"999999"]) {
    NSLog(@"==>PARAMETER is SSSSSS (999999)");
} else {
    NSLog(@"==>PARAMETER is EEEEEE (000000)");
}
NSLog(@" ");

//==== CHECK IF DATABASE NEEDS TO BE UPDATED ====//
if ([[qArray objectAtIndex:2] isEqualToString: k_DBVERSION]) {
    // No update needed
    NSLog(@"==> No update needed");
    NSLog(@" ");
}
else {
    NSLog(@"==> Update needed");
    NSLog(@" ");
    NSLog(@" ");
    NSLog(@"=======================");
    NSLog(@"====BEFORE REPLACE====");
    if ([[qArray objectAtIndex:2] isEqualToString:@"000000"]) {
        NSLog(@"===>CURRENT: EEEEEE: %@", [qArray objectAtIndex:2]);
    } else {
        NSLog(@"===>CURRENT: SSSSSS: %@", [qArray objectAtIndex:2]);
    }

    [self replaceDatabase];
}

qArray = [refreshDB_function readQuestion: 999999];
NSLog(@" ");
NSLog(@" ");
NSLog(@"=======================");
NSLog(@"=====AFTER REPLACE=====");
NSLog(@"=======================");
if ([[qArray objectAtIndex:2] isEqualToString:@"000000"]) {
    NSLog(@"Updated database is EEEEEE");
} else {
    NSLog(@"Updated database is SSSSSS");
}

NSLog(@" "); 
NSLog(@"========>STOP<=========");
NSLog(@" ");

exit(0); //>>>>STOP HERE DURING TESTING

return YES;
}

replaceDatabase:

- (void)replaceDatabase {
NSLog(@"=======================");
NSLog(@"replaceDatabase function");
NSLog(@"=======================");
NSLog(@" ");

NSFileManager *fileManager = [NSFileManager defaultManager];

// remove old sqlite database from documents directory
NSURL *dbDocumentsURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"database.sqlite"];
NSString *dbDocumentsPath = [dbDocumentsURL path];

//====Cache directory testing====//
//====This is just for testing====//

//===============================//
NSLog(@"=======================");
NSLog(@"    DELETE CACHE");
NSLog(@"=======================");
NSLog(@" ");
if ([fileManager removeItemAtPath: [NSHomeDirectory() stringByAppendingString:@"/Library/Caches"] error: NULL]  == YES)
    NSLog (@"Remove successful");
 else 
    NSLog (@"Remove failed");

NSLog(@"=======================");
NSLog(@"    CREATE NEW CACHE");
NSLog(@"=======================");
NSLog(@" ");    

[fileManager createDirectoryAtPath: [NSHomeDirectory() stringByAppendingString:@"/Library/Caches"] withIntermediateDirectories:NO attributes:nil error:nil];

//===============================//
NSLog(@"===============================");
NSLog(@"REMOVE sqlite FROM DOCUMENT DIR");
NSLog(@"===============================");
NSLog(@" ");


if ([fileManager fileExistsAtPath:dbDocumentsPath]) {
    NSError *error = nil;
    [fileManager removeItemAtPath:dbDocumentsPath error:&error];
    NSLog(@"removeItemAtPath:dbDocumentsPath: %@",dbDocumentsPath);
    NSLog(@" ");

    if (error) {
        NSLog(@"Error deleting sqlite database: %@", [error localizedDescription]);
    }
} else {
    NSLog(@"file does not ExistsAtPath:dbDocumentsPath: %@",dbDocumentsPath);
    NSLog(@" ");
}


NSLog(@"=====================================");
NSLog(@"CHECK IF sqlite EXIST IN DOCUMENT DIR");
NSLog(@"=====================================");
NSLog(@" ");
if ([fileManager fileExistsAtPath:dbDocumentsPath]) {
    NSLog(@"===FILE EXIST===");
} else {
    NSLog(@"===FILE DOES NOT EXIST===");
}
 NSLog(@" ");    


// move new sqlite database from bundle to documents directory
NSLog(@"========================================");
NSLog(@"MOVE sqlite FROM BUNDLE TO DOCUMENTS DIR");
NSLog(@"========================================");
NSLog(@" ");
NSString *dbBundlePath = [[NSBundle mainBundle] pathForResource:@"database" ofType:@"sqlite"];
if (dbBundlePath) {
    NSError *error = nil;
    [fileManager copyItemAtPath:dbBundlePath toPath:dbDocumentsPath error:&error];
    NSLog(@"==>copyItemAtPath:dbBundlePath<<");
    if (error) {
        NSLog(@"Error copying sqlite database: %@", [error localizedDescription]);
    }
}

NSLog(@"=====================================");
NSLog(@"CHECK IF sqlite EXIST IN DOCUMENT DIR");
NSLog(@"=====================================");
NSLog(@" ");
if ([fileManager fileExistsAtPath:dbDocumentsPath]) {
    NSLog(@"===FILE EXIST===");
} else {
    NSLog(@"===FILE DOES NOT EXIST===");
}
NSLog(@" ");
}

persistentStoreCoordinator:

// If the coordinator doesn't already exist, it is created and the application's store added to it.
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
NSLog(@"persistentStoreCoordinator");

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

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"database.sqlite"];
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;
}

readQuestion:

- (NSMutableArray *)readQuestion: (int)questionNr {

NSLog(@"readQuestion");

NSMutableArray *read_Question = [[NSMutableArray alloc] initWithCapacity: 0];

NSError *error;
//=========PREPARE CORE DATA DB===========//
if (managedObjectContext == nil) { managedObjectContext = [(xxxxxAppDelegate *)
                                                           [[UIApplication sharedApplication] delegate] managedObjectContext]; }
// Define qContext
NSManagedObjectContext *qContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription 
                               entityForName:@"questions" inManagedObjectContext:qContext];
[fetchRequest setEntity:entity];

NSString *qNR = [NSString stringWithFormat:@"%d", questionNr];

if (questionNr == 999999) { // This is the call to check if database should be updated
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"(question = %@)", @"Hur mycket är 37532 * 3?"];
    [fetchRequest setPredicate: pred];
}
else {
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"(idQ = %@)", qNR];
    [fetchRequest setPredicate: pred];
}


NSManagedObject *matches = nil;

NSArray *objects = [qContext executeFetchRequest:fetchRequest error:&error];

if ([objects count] == 0) {     // If no match refresh database
    [read_Question addObject:@"Update_DB"];
    [read_Question addObject:@"Update_DB"];
    [read_Question addObject:@"Update_DB"];
    [read_Question addObject:@"Update_DB"];
} else {
    matches = [objects objectAtIndex:0];
    [read_Question addObject:[matches valueForKey:@"question"]];
    [read_Question addObject:[matches valueForKey:@"qRightAnswer"]];
    [read_Question addObject:[matches valueForKey:@"qWrongAnswer1"]];
    [read_Question addObject:[matches valueForKey:@"qWrongAnswer2"]];
}

[fetchRequest release];

return [read_Question autorelease];
}

1 个答案:

答案 0 :(得分:0)

嗯,有趣的问题。我有一个理论。首先,如果我正确地读取您的代码,您将获得持久性存储协调器以便找出数据库版本。这是创建一个持久存储协调器,它引用旧的sqlite文件。这是我不确定的部分。我怀疑,因为它具有旧文件的句柄,即使你删除它,持久存储协调器仍然指旧的。您可能想要尝试的一件事是删除并替换sqlite文件后,将持久存储协调器和受管对象上下文取消。此外,我会尝试简单地假设sqlite已过时并在初始化持久存储协调器和托管对象上下文之前替换它。