2012-10-12 83 views
1

當用戶升級或重新安裝較新版本的iOS應用程序時,是否有任何委託方法會被調用?ios應用程序升級代表

我使用核心數據從服務器緩存一些信息。當任何實體的模式發生變化時,我需要從模擬器手動刪除SQLite數據庫,否則應用程序將在啓動時崩潰,並出現錯誤「用於打開商店的模型與用於創建商店的模型不兼容「。如果有任何應用程序升級的委託方法,則可以自動執行刪除操作。

回答

4
+0

感謝您的鏈接。也許這不值得版本控制的複雜性,因爲它只是一個緩存,並且我總是可以從服務器中恢復其中的信息。在AppDelegate的' - (NSPersistentStoreCoordinator *)persistentStoreCoordinator'的默認實現中的註釋給了我使用的解決方案:'[[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil];'當它失敗時[_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType配置:無URL:storeURL選項:無錯誤:錯誤]' –

2

丹尼爾·史密斯的答案是正確的,但我只想補充我的應用程序如何確定其被更新。我看在默認情況下保留一個'當前版本'字符串。當應用程序啓動時,我把它比作當前版本:

  • 默認已經沒有字符串 - 這是程序的第一個運行
  • 默認版本是不同的 - 用戶更新應用
  • 默認是相同的 - 用戶剛剛重新啓動應用程序

有時很高興知道上述。確保在設置標籤後立即保存默認值並進行所需的版本控制,因此崩潰不會再次執行。

編輯:如果他模型的變化如何不崩潰。我現在使用它,保留舊的存儲庫,並調整模型,每調整一次,它就刪除舊的(如果它無法打開它)並創建一個新的。這是模仿蘋果的代碼,但不知道我做了什麼改變。在任何情況下,如果模型更改,您都不會崩潰。

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator 
{ 
    //LTLog(@"_persistentStoreCoordinator = %@", _persistentStoreCoordinator); 
    if (_persistentStoreCoordinator) 
    { 
     return _persistentStoreCoordinator; 
    } 
    NSFileManager *manager = [NSFileManager defaultManager]; 
    NSString *path = [[appDelegate applicationAppSupportDirectory] stringByAppendingPathComponent:[_dbName stringByAppendingPathExtension:@"SQLite"]]; 
    storeURL = [NSURL fileURLWithPath:path]; 

    BOOL fileExists = [manager fileExistsAtPath:path]; 
    if(!fileExists) { 
     _didCreateNewRepository = YES; 
    } 
    if(_createNewRepository) { 
     [manager removeItemAtURL:storeURL error:nil]; 
     if(fileExists) _didDestroyOldRepository = YES; 
     _didCreateNewRepository = YES; 
    } 

    while(YES) { 
     __autoreleasing NSError *error = nil; 
     _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 
     if ([_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) { 

      break; 
     } else { 
      _persistentStoreCoordinator = nil; 
      [manager removeItemAtURL:storeURL error:&error]; 
      if(fileExists) { 
       _didDestroyOldRepository = YES; // caller didn't want a new one but got a new one anyway (old one corrupt???) 
       _didCreateNewRepository = YES; 
      } 
#ifndef NDEBUG 
      LTLog(@"CORE DATA failed to open store %@: error=%@", _dbName, error); 
#endif 
      /* 
      Replace this implementation with code to handle the error appropriately. 

      abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button. 

      Typical reasons for an error here include: 
      * The persistent store is not accessible 
      * The schema for the persistent store is incompatible with current managed object model 
      Check the error message to determine what the actual problem was. 
      */ 
      //LTLog(@"Unresolved error %@, %@", error, [error userInfo]); 
      //abort(); 
     }  
    } 
    return _persistentStoreCoordinator; 
} 
+0

好主意。我將保存它以供將來使用。 –