我的应用程序不更新只读的Core Data sqlite数据库的新版本 [英] My app does not update the new version of read-only Core Data sqlite database

查看:161
本文介绍了我的应用程序不更新只读的Core Data sqlite数据库的新版本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

==== MY SOLUTION ====
我通过将数据库存储在主包中并在每次更新应用程序时更改数据库名称来解决此问题。

====MY SOLUTION==== I solved this by storing the database in the Main Bundle and change the name of the database every time i updated the app.

我曾经考虑刷新模型等,但没有真正让我的工作,因为我想要的。

I did look into refreshing the model etc. but didn't really get that to work as i wanted.

我如何解决这个问题

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

我真的道歉,我已经问过这个问题,在不同的格式,之前,但我还没有能够解决它,可能是由于我问的问题。我删除了以前的问题。

I do apologize that i have asked this question, in different formats, before but i have not been able to solve it, probably due to how i asked the question. I did delete the old questions.

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

I have an app using a Core Data sqlite read/only database and i am trying to update the app with a new version (version# inbeded in a record) of the database. Whatever i do, except manually clean target and reset simulator, it still read the old database. I need to be able to do this via code.

在初始设计期间我发布以下尝试解决相同的问题:初始设计

During the initial design i posted the following to try to solve the same problem: The initial design. Now the database is so big it takes a lot of time to build it at first start.

这个过程:

A。)我将新数据库版本添加到XCODE项目,并通过Xcode

A.) I add the new database version to the XCODE project and also manually add it to the bundle via Xcode

B手动将其添加到捆绑包中。我检查数据库的版本使用

B.) I check what version of the database is used

C。)如果有一个新的数据库,我删除文件目录中的旧数据库,然后从主包到文档目录

C.) If there is a new database i delete the old database in the documents directory and then copy the new version from the main bundle to the document directory

D)。在附加的代码中,我也删除了Cache目录并重新创建它,我发现了一些帖子指出,可能是原因。

D.) In the attached code i also delete the Cache directory and recreate it, I found a number of posts that pointed out that the cache could be the reason. This is just for testing but is still included in the code

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

Despite this the app still not access the updated sqlite database.

我有一个新的数据库版本加载在主包,我有一个版本参数EEEEEE,当我读取当前数据库,它有SSSSSS参数,所以数据库应该更新。

I have a new database version loaded in the main bundle, I have a version parameter "EEEEEE", when i read the current database it has "SSSSSS" parameter so the database should be updated.

我一直在使用这个问题,并在网上搜索了很长时间,我只是不明白是什么问题。为什么它不能访问文档目录中的新数据库。

I have been working with this problem, and searched the web, for a long time and i just can not understand what is wrong. Why does it not access the new database in the documents directory.

我感谢所有的帮助,我可以得到。我希望代码看起来不奇怪,因为我包括我的NSLog的,我用来试图了解发生了什么。

I am appreciate all help i can get. I hope the code doesn't look to weird as i have included my NSLog's that i use to try to understand what is happening.

trace(NSLog):



The trace (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:

Here is the code from the 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:

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:

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:

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


推荐答案

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

Hmm, interesting question. I have a theory though. First of all, if I'm reading your code correctly, you are getting a Persistent Store Coordinator in order to figure out the db version. This is creating a Persistent Store Coordinator that refers to the old sqlite file. This is the part I'm not sure about. I suspect that since it has the handle to the old file, even though you delete it, the Persistent Store Coordinator is still referring to the old one. One thing you might want to try is nil-ing out the Persistent Store Coordinator and the Managed object Context after you delete and replace the sqlite file. Also, I would try simply assuming the sqlite is outdated and replacing it before initializing the Persistent Store Coordinator and Managed Object Context.

这篇关于我的应用程序不更新只读的Core Data sqlite数据库的新版本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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