1

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

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

我是如何解决这个问题的

====原来的问题====

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

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

在初始设计期间,我发布了以下内容以尝试解决相同的问题:初始设计。现在数据库太大了,第一次开始构建它需要很多时间。

过程:

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

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

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

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

尽管如此,该应用程序仍然无法访问更新的 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;
}

替换数据库:

- (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(@" ");
}

持久存储协调器:

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

阅读问题:

- (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];
}
4

1 回答 1

0

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

于 2012-07-16T21:27:04.050 回答