2012-07-15 74 views
2

我使用主包中的只讀核心數據源,效果很好。當我將新版本的數據庫(更多隻讀數據)添加到主包時,它仍會讀取數據庫的「舊」版本。在主包中更新只讀核心數據sqlite

任何人都可以幫助我理解當前用戶使用新版本的數據庫下載更新時爲什麼以及如何獲取新數據庫版本?

這是試圖解決在這個崗位問題的一部分:Same problem when accessing updated database from documents directory

===解決方案====

我解決了這個由「新」改變新數據庫的名稱主捆綁,它像夢一樣工作。另外,如果這是更新,我將刪除文檔目錄中的舊數據庫以進行清理。

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator { 

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


//===READ DATABASE FROM MAIN BUNDLE===// 
NSFileManager *fileManager = [NSFileManager defaultManager]; 

NSURL *storeUrl = [[NSBundle mainBundle] URLForResource:kNewDB withExtension:@"sqlite"]; 

//=== IF THE OLD DATABASE STILL EXIST DELETE IT FROM DOCUMENT DIRECTORY ===// 
NSURL *oldDatabasePathURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"database.sqlite"]; 
NSString *oldDatabasePath = [oldDatabasePathURL path]; 
if ([fileManager fileExistsAtPath:oldDatabasePath]) { 
    //Remove old database from Documents Directory 
    [fileManager removeItemAtURL:oldDatabasePathURL error:nil]; 

} 

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; 

persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]]; 

NSError *error; 
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) { 
    // Update to handle the error appropriately. 
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
    exit(-1); // Fail 
}  

return persistentStoreCoordinator; 
} 
+0

您的意思是新的數據庫文件沒有複製到目標(即生成的應用程序包)? – diederikh 2012-07-15 14:21:43

+0

我認爲這是應用程序繼續讀取舊數據庫時的問題。我想我是乾淨的目標等等。但是當我從appstore下載當前用戶時,我應該怎麼做? – PeterK 2012-07-15 16:15:31

回答

2

你必須在你的代碼的一個地方,你檢查,看看是否在某些可寫目錄(可能是你的文檔目錄)中存在的數據庫文件的副本,如果沒有,那麼你複製它。當您需要更改數據庫時,這是一種非常常見的方法。問題是,當你更新你的應用時,該文件已經存在,所以它永遠不會被複制。

有拿地解決您的問題兩種方式:

  1. (優先):不要擺在首位的數據庫複製。由於它是隻讀的,你不需要,它只是佔用設備上的額外空間。只需使用主包中文件的路徑打開數據庫即可。

  2. 而不是檢查在可寫目錄中是否存在文件,檢查它是否比主包中的更新。 (而不是使用日期,因爲他們可能已經安裝了程序並在更新提交給應用商店進行批准後創建了該文件,這會導致新的文件不會被複制,您需要檢查數據庫,可能通過在應用程序包中存儲另一個文件來存儲版本信息,或者使用特定於版本的代碼來確定它)。如果不是,則再次複製它。

+0

嗨,我知道它是隻讀的,所以也是我的數據庫,所以沒有衝突,因爲我從主包中讀取。這是當我提交更新數據庫與額外的只讀數據我需要開始使用它。但是,該應用程序仍然讀取數據庫的舊版本。 – PeterK 2012-07-15 16:13:53

+0

對不起,我誤解了你在問什麼。看看我更新的答案! – lnafziger 2012-07-15 22:13:26

1

PeterK,當使用http://www.raywenderlich.com/12170/core-data-tutorial-how-to-preloadimport-existing-data-updated教程來使用Core Data的只讀sqlite數據庫時,我遇到了同樣的問題。一切都很好,直到我不得不更新我的數據庫並重新發布我的目標應用程序。如您所知,如果Application的Documents目錄中不存在數據庫,則該教程中的建議代碼只會複製到新數據庫中。

我不認爲重命名我的數據庫(和更新複製代碼)是一個很好的設計方法,所以我通過遵循Inafziger的首選建議並閱讀iOS文件結構來獲得我的設計工作。我僅提供以下內容來展示如何實施Inafziger的建議。值得注意的是,這種方法可能只適用於如果您的應用程序不以只讀方式讀入核心數據信息的內容。

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator 
{ 
    if (_persistentStoreCoordinator != nil) { 
    return _persistentStoreCoordinator; 
    }  

    // Updated processing to now just have the NRPersistentStoreCoordinator point to the sqlite db in the 
    //   application's Bundle and not by copying that db to the app's Documents directory and then using 
    //   the db in the Documents directory. 
    NSURL *refactoredStoreURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@「NameOfYourDatabase ofType:@"sqlite"]]; 


    NSError *error = nil; 

    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 

    // Added to ensure the NSPersistentStoreCoordinator reads the Bundle's db file as read-only since 
    //   it is not appropriate to allow the app to modify anything in the Bundle 
    NSDictionary *readOnlyOptions = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSReadOnlyPersistentStoreOption, nil]; 

    // Use the URL that points to the Bundle's db file and used the ReadOnly options 
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:refactoredStoreURL options:readOnlyOptions error:&error]) { 
    // Your logic if there is an error 
    } 
    return _persistentStoreCoordinator; 
} 

我希望這可以幫助下一個這個問題的讀者。

+0

謝謝,這很有趣:-) – PeterK 2014-01-01 12:56:38