2010-11-10 60 views
1

和很多人一樣,我必須在模擬器中刪除我的應用程序,以便重新安裝新版本,在那裏更新我的數據庫。否則,它會崩潰,有或沒有調試日誌(如果它是核心數據,調試日誌是非常明顯的)。iPhone應用商店更新系統​​,以及對數據庫的影響

我的問題是:因爲用戶不會可能通過App Store更新前刪除他們的應用程序,並且因爲他們將最肯定要在升級後的「老」的數據,

我們有開發一個數據庫遷移腳本,或者在每次啓動時檢查數據庫是否發生更改的applicationDidLaunch?

謝謝!

+0

看來,這是一個問題,更多的SQLite比核心數據。是? – westsider 2010-11-10 16:50:27

+0

這是一個普遍的問題,因爲當時我想知道在「應用商店」升級過程中發生了什麼。我目前的應用程序使用SQLite雖然 – 2010-11-10 17:00:34

回答

1

我沒有親自使用過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"]; 
} 
3

我一定會給你一個1星,如果我的數據是更新後丟失。
Core-Data版本控制和遷移是在幾分鐘內完成的,至少是輕量級的部分。

看一看這個answer爲類似的問題

+0

然後我不會告訴你我的應用程序名稱^^不,認真,如果我問,這是因爲我關心這種可能性。我一定會檢查你的鏈接,但目前,我會建立一個腳本,因爲它是一個SQLite應用程序 – 2010-11-10 14:26:36

+0

+1他說的是真實的。您不需要 - (甚至可能無法運行)「腳本」來執行遷移。但是Core Data有一些東西可以幫助你做這種類型的版本到版本的遷移。是的,如果我擁有你的應用程序並在更新時丟失了我的數據,那麼我將會非常榮幸地成爲...PS不要自動相信以「我沒有親自使用CoreData,因此不知道它是否有特殊的工具來處理這個問題」爲開頭的答案 – Brad 2010-11-10 14:58:56

+0

我讀這個問題是關於遷移處理的一般問題,而不是如何完成這個在CoreData中。但是,因爲它有點含糊,我用「這個答案不適用於CoreData的評論」作爲前言。根據OP的最新評論,他實際上並沒有使用CoreData。但你的答案是我的嗎? – aepryus 2010-11-10 15:14:57

相關問題