2012-01-09 14 views
17

私はアプリストアにデータを読み込むためにsqliteデータベースを使用するバージョン1.0のアプリを持っています。
今、データベースファイルの更新でバージョンを1.1に更新したいと思います。
デバイスにアプリケーションをインストールするときに開発者証明書を使用している間に、データベースファイルがドキュメントフォルダに既に存在するためデータベースを更新しなかったので、手動でアプリケーションを削除してもう一度インストールする必要があります。
私の質問は、任意のユーザーがアプリケーションを更新すると、データベースも現在のバージョンに応じて更新されます。
提案は大歓迎です。
おかげiPhoneのAppstoreでアプリのバージョンが変更されたときのsqliteデータベースの更新

+0

データは読み取り専用か、読み書き可能ですか? –

+0

データは読み取り専用です。 –

答えて

14

は、私がこれを行うには、多くの方法(および多くの方法が同様に鉱山そしてより良い)があると確信していますが、次のように、私はこのような問題を処理する方法は次のとおりです。

まず私は定数を定義しますはじめての負荷を示し、0に設定するアプリ(最初にロードされます1)の最初の.hファイル:

#define FirstTime 0 

今、あなたは、私がこの定数の値を保存する意思を持っていることを知っている必要がありますしたがって、私は共有データインスタンスを使用します。 viewDidLoadで、私は次のテストを実行します。

//if first time run of this version 
if([MyDataModel sharedInstance].count < (FirstTime + 1)) 
{ 
    //do what you need to do as the first time load for this version 

    [MyDataModel sharedInstance].count++ 
    //save the count value to disk so on next run you are not first time 
    //this means count = 1 
} 

今のトリックは、あなたの新しいアプリのバージョン(例えば1.1)です。私は2にFirstTimeを変更します。

#define FirstTime 2 

ディスク上に保存された初めての値が1であるので、これはあなたが上記のif文によってキャッチされることを意味し、古いテーブルを削除するように、したがってその中にあなたが欲しいものを行うことができます新しい地層でそれらを再現してください。

もう華麗ではありませんが、ケースを解決してください!

- (void)isItTheFirstTimeAfterUpdate { 
    NSString *versionnum; 
    NSError *error; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, 
                 NSUserDomainMask, 
                 YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *path = [documentsDirectory stringByAppendingPathComponent:@"yourplist.plist"]; 
    NSFileManager *fileManager = [NSFileManager defaultManager]; 

    if(![fileManager fileExistsAtPath:path]) { 
     NSString *bundle = [[NSBundle mainBundle] pathForResource:@"yourplist" ofType:@"plist"]; 
     [fileManager copyItemAtPath:bundle toPath:path error:&error]; 
    } 

    NSMutableDictionary *savedStock = [[NSMutableDictionary alloc] initWithContentsOfFile:path]; 
    versionnum = @""; 
    //it can be installed by user (for ex. it is 1.3 but first installed), no plist value is set before 
    if(([savedStock objectForKey:@"versionnum"]) && (![[savedStock objectForKey:@"versionnum"] isEqualToString:@""])){ 
     versionnum = [savedStock objectForKey:@"versionnum"]; 
    } 

    //to get the version of installed/updated-current app 
    NSString *myversion = [NSString stringWithFormat:@"%@",[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]]; 
    //if no version has been set-first install- or my version is the latest version no need to do sth. 
    if ([versionnum isEqualToString:myversion] || [versionnum isEqualToString:@""]) { 
     NSLog(@"Nothing has to be done"); 
    } 
    else { 
     [self cleanDB];//i have clean tables and create my new db tables maybe logout the user etc. 
     [savedStock setObject:[NSString stringWithString:myversion] forKey:@"versionnum"];//setting the new version 
     [savedStock writeToFile:path atomically:YES]; 
    } 
} 

をそして、あなたはあなたの選択...アプリケーションの起動やメインビューコントローラのビューコントローラ内の関数を呼び出すことができます。

6

あなたにも.plistを使用することができます。

願っています。

12

この方法はNSUserDefaultsに依存しています。アイデアは、NSUserDefaultsから以前のアプリケーションのバージョン番号(存在する場合)を取得し、それを現在のバージョンと比較することです。

以前のバージョンのアプリケーションが現在のバージョンより<である場合、または以前のバージョンがnilの場合、コードはdbのアップグレードを実行します。これは、AppStoreに既に公開されていても、このアプローチを使用できることを意味します。アプリのアップデート中にデータベースを新しいバージョンにアップグレードします。

これはplistファイルである:バージョン番号と対応するアップグレードバージョンのSQLクエリのセットで構成されたアレイがあり

enter image description here

。 前のバージョンが1.2で、実際のバージョンが1.4であると仮定すると、コードはバージョン1.2から1.4へのアップグレードのみを実行します。以前のバージョンが1.3で現在の1.4の場合、コードは1.3から1.4へのアップグレードのみを実行します。 以前のバージョンがnilの場合、コードは1.1へのアップグレード、1.2へのアップグレード、1.3へのアップグレード、最後に1.4へのアップグレードを実行します。

NSString * const VERSION_KEY = @"version"; 

-(void)upgradeDatabaseIfRequired{ 
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
    NSString *previousVersion=[defaults objectForKey:VERSION_KEY]; 
    NSString *currentVersion=[self versionNumberString]; 

    if (previousVersion==nil || [previousVersion compare: currentVersion options: NSNumericSearch] == NSOrderedAscending) { 
     // previous < current 
     //read upgrade sqls from file 
     NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"UpgradeDatabase" ofType:@"plist"]; 
     NSArray *plist = [NSArray arrayWithContentsOfFile:plistPath]; 


     if (previousVersion==nil) {//perform all upgrades 
      for (NSDictionary *dictionary in plist) { 
       NSString *version=[dictionary objectForKey:@"version"]; 
       NSLog(@"Upgrading to v. %@", version); 
       NSArray *sqlQueries=[dictionary objectForKey:@"sql"]; 
       while (![DB executeMultipleSql:sqlQueries]) { 
        NSLog(@"Failed to upgrade database to v. %@, Retrying...", version); 
       }; 
      } 
     }else{ 
      for (NSDictionary *dictionary in plist) { 
       NSString *version=[dictionary objectForKey:@"version"]; 
       if ([previousVersion compare: version options: NSNumericSearch] == NSOrderedAscending) { 
        //previous < version 
        NSLog(@"Upgrading to v. %@", version); 
        NSArray *sqlQueries=[dictionary objectForKey:@"sql"]; 
        while (![DB executeMultipleSql:sqlQueries]) { 
         NSLog(@"Failed to upgrade database to v. %@, Retrying...", version); 
        }; 
       } 

      } 
     } 

     [defaults setObject:currentVersion forKey:VERSION_KEY]; 
     [defaults synchronize]; 
    } 

} 


- (NSString *)versionNumberString { 
    NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary]; 
    NSString *majorVersion = [infoDictionary objectForKey:@"CFBundleShortVersionString"]; 
    return majorVersion; 
} 
関連する問題