和很多人一樣,我必須在模擬器中刪除我的應用程序,以便重新安裝新版本,在那裏更新我的數據庫。否則,它會崩潰,有或沒有調試日誌(如果它是核心數據,調試日誌是非常明顯的)。iPhone應用商店更新系統,以及對數據庫的影響
我的問題是:因爲用戶不會可能通過App Store更新前刪除他們的應用程序,並且因爲他們將最肯定要在升級後的「老」的數據,
我們有開發一個數據庫遷移腳本,或者在每次啓動時檢查數據庫是否發生更改的applicationDidLaunch?
謝謝!
和很多人一樣,我必須在模擬器中刪除我的應用程序,以便重新安裝新版本,在那裏更新我的數據庫。否則,它會崩潰,有或沒有調試日誌(如果它是核心數據,調試日誌是非常明顯的)。iPhone應用商店更新系統,以及對數據庫的影響
我的問題是:因爲用戶不會可能通過App Store更新前刪除他們的應用程序,並且因爲他們將最肯定要在升級後的「老」的數據,
我們有開發一個數據庫遷移腳本,或者在每次啓動時檢查數據庫是否發生更改的applicationDidLaunch?
謝謝!
我沒有親自使用過CoreData,所以不知道它是否有特殊的工具來處理這個問題。但是,一般來說,您需要創建並存儲將從每個應用版本遷移到下一個版本的SQL腳本。
安裝應用程序時,應該根據應用程序使用的數據模型的版本檢查數據模型的當前版本。應該有一個「增量」腳本從每個版本移動到每個下一個版本。然後應用每個從當前模型轉換到必要模型所需的三角洲。
例如,如果您已向AppStore提交了4個版本。您需要從版本1到版本2,從2到3以及從3到4獲取版本腳本。
每次啓動應用程序時,都會根據所需的可執行版本檢查數據模型的當前版本。例如,如果在設備上安裝了版本4,但用戶從未安裝過版本3,則應用程序將啓動。檢查模型的當前版本,即2.將其與可執行文件的版本4進行比較。然後應用2到3腳本,然後應用3到4腳本。
版本號本身可以存儲在數據庫中,應該在應用deltas之後遞增,無論是從deltas本身還是自動處理代碼。
deltas可以作爲常量字符串存儲在代碼文件中,也可以作爲項目中的資源文件存儲。
編輯:(這裏是我的遷移代碼)
+ (NSArray*) chop:(NSString*)sql {
NSMutableArray* list = [[NSMutableArray alloc] init];
NSMutableString* sb = [[NSMutableString alloc] init];
BOOL inside = FALSE;
for (int i=0;i<[sql length];i++) {
if ([sql characterAtIndex:i] == '\n') continue;
if ([sql characterAtIndex:i] == '\r') continue;
[sb appendFormat:@"%c",[sql characterAtIndex:i]];
if (!inside) {
if ([sql characterAtIndex:i] == '\'')
inside = TRUE;
else if ([sql characterAtIndex:i] == ';') {
[sb deleteCharactersInRange:NSMakeRange([sb length]-1,1)];
[list addObject:sb];
[sb release];
sb = [[NSMutableString alloc] init];
}
} else {
if ([sql characterAtIndex:i] == '\'')
inside = FALSE;
else if ([sql characterAtIndex:i] == '\\') {
i++;
[sb appendFormat:@"%c",[sql characterAtIndex:i]];
}
}
}
[sb release];
return [list autorelease];
}
+ (void) updateObjectModel {
[Log output:@"[migration]"];
int version;
@try {
int exist = [SQL queryLong:@"SELECT COUNT(*) FROM Variables WHERE Key='objectModelVersion'"];
if (exist)
version = [SQL retrieveInt:@"objectModelVersion"]+1;
else {
[Log output:@"[bootstrapping]"];
[SQL storeInt:@"objectModelVersion" as:1];
version = 2;
}
} @catch (NSException* e) {
[Log output:@"[initializing]"];
version = 0;
}
while (TRUE) {
NSString* filename = [NSString stringWithFormat:@"SQLite-%04d",version];
NSString* file = [[NSBundle mainBundle] pathForResource:filename ofType:@"sql"];
if (file) {
[Log output:[NSString stringWithFormat:@"[%d]",version]];
NSArray* commands = [SQL chop:[NSString stringWithContentsOfFile:file encoding:NSASCIIStringEncoding error:NULL]];
for (NSString* command in commands)
[SQL update:command];
[SQL storeInt:@"objectModelVersion" as:version];
} else break;
version++;
}
[Log output:@"[/migration]\n"];
}
我一定會給你一個1星,如果我的數據是更新後丟失。
Core-Data版本控制和遷移是在幾分鐘內完成的,至少是輕量級的部分。
看一看這個answer爲類似的問題
然後我不會告訴你我的應用程序名稱^^不,認真,如果我問,這是因爲我關心這種可能性。我一定會檢查你的鏈接,但目前,我會建立一個腳本,因爲它是一個SQLite應用程序 – 2010-11-10 14:26:36
+1他說的是真實的。您不需要 - (甚至可能無法運行)「腳本」來執行遷移。但是Core Data有一些東西可以幫助你做這種類型的版本到版本的遷移。是的,如果我擁有你的應用程序並在更新時丟失了我的數據,那麼我將會非常榮幸地成爲...PS不要自動相信以「我沒有親自使用CoreData,因此不知道它是否有特殊的工具來處理這個問題」爲開頭的答案 – Brad 2010-11-10 14:58:56
我讀這個問題是關於遷移處理的一般問題,而不是如何完成這個在CoreData中。但是,因爲它有點含糊,我用「這個答案不適用於CoreData的評論」作爲前言。根據OP的最新評論,他實際上並沒有使用CoreData。但你的答案是我的嗎? – aepryus 2010-11-10 15:14:57
看來,這是一個問題,更多的SQLite比核心數據。是? – westsider 2010-11-10 16:50:27
這是一個普遍的問題,因爲當時我想知道在「應用商店」升級過程中發生了什麼。我目前的應用程序使用SQLite雖然 – 2010-11-10 17:00:34