web-dev-qa-db-ja.com

iPhoneコアデータ「自動軽量移行」

コアデータストアを実装するアプリを更新しようとしています。エンティティの1つに属性を追加しています。

次のコードをデリゲートクラスに追加しました。

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

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

    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"Shoppee.sqlite"]];

    NSError *error = nil;
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

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

    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
        NSLog(@"Error: %@",error);
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }    

    return persistentStoreCoordinator;
}

これは次のURLからのものです: Doc

コードを実行すると、次のエラーが発生します。

2009-12-01 20:04:22.877

Shoppee [25633:207]エラー:エラー

ドメイン= NSCocoaErrorドメインコード= 134130

UserInfo = 0x1624d20 "操作を完了できませんでした。(Cocoaエラー134130。)" 2009-12-01 20:04:22.879 Shoppee [25633:207]未解決のエラーエラードメイン= NSCocoaErrorDomainコード= 134130 UserInfo = 0x1624d20 "操作を実行できませんでした(Cocoaエラー134130。) "、{URL = file:// localhost/Users/Eric/Library/Application%20Support/iPhone%20Simulator/User/Applications/A8A8FB73-9AB9-4EB7-8F83-82F5B4467AF1/Documents/MyApp .sqlite;メタデータ= {NSPersistenceFrameworkVersion = 241; NSStoreModelVersionHashes = {Item = <869d4b20 088e5c44 5c345006 87d245cd 67ab9bc4 14cadf45 180251e9 f741a98f>; Store = <47c250f4 895e6fd1 5033ab42 22d2d493 7819ba75 3c0acffc 2dc54515 8deeed7a>; }; NSStoreModelVersionHashesVersion = 3; NSStoreModelVersionIdentifiers =(); NSStoreType = SQLite; NSStoreUUID = "8DC65301-3BC5-42BE-80B8-E44577B8F8E1"; }; reason = "ソースストアのモデルが見つかりません"; }

どういうわけか元のデータモデルを含める必要があるようですが、それを行う方法がわかりません。助言がありますか?

64
Eric

要約/完全ガイド:

  1. 変更を加える前に、新しいモデルバージョンを作成します。

    Xcode 4では、.xcdatamodel-> Editor-> Add Model Versionを選択します。

    Xcode 3:デザイン->データモデル->モデルバージョンの追加。

    新しい.xcdatamodel.xcdatamodeldフォルダーに作成されます(これもない場合は作成されます)

  2. セーブ。

  3. 新しい.xcdatamodelを選択し、 theLightweight Migrationdocumentation に従って採用したい変更を行います。

  4. セーブ。

  5. 現在/アクティブなスキーマを新しく作成したスキーマに設定します。

    .xcdatamodeldフォルダーを選択した場合:

    Xcode 4:ユーティリティのサイドバー->ファイルインスペクター->バージョン付きコアデータモデル->新しいスキーマを選択します。

    Xcode 3:デザイン>データモデル>現在のバージョンを設定します。

    .xcdatamodelアイコンの緑色のチェックマークが新しいスキーマに移動します。

  6. セーブ。

  7. 実行時に移行を実行するために必要なコードを実装します。

    NSPersistentStoreCoordinatorが作成されている場所(通常はAppDelegateクラス)のoptionsパラメーターで、nilを次のコードに置き換えます。

    [NSDictionary dictionaryWithObjectsAndKeys:
                      [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, 
                      [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]
    
  8. アプリを実行します。クラッシュがない場合は、おそらく正常に移行されています。

  9. 正常に移行したら、移行コード(ステップ7)を削除できます。 (公開されたアプリのユーザーがいつ移行したと見なすことができるかを決定するのは開発者の責任です。)

重要:古いモデルバージョン/スキーマは削除しないでください。 Core Dataが新しいバージョンに移行するには、古いバージョンが必要です。

143
Stian Høiland

私はそれを考え出した。

設計>データモデル>モデルバージョンの追加

26
Eric

再びGoogle社員にとって、これはあなたがする必要があることです(すでにLightweight Migrationをセットアップしていると想定しています):

  1. 変更を行う前に、デザインを実行->データモデル->モデルバージョンを追加.xcdatamodelフォルダーに新しい.xcdatamodeldが作成されていることがわかります)
  2. セーブ
  3. 変更を加えます
  4. セーブ
  5. アプリを実行

ステップ1は、この作業を行うために重要です。これらの手順に従って新しいフィールドを追加したため、この問題に遭遇しました。うまくいきました。 2番目の新しいフィールドを追加しましたが、「モデルバージョンの追加」を忘れてしまい、問題が発生しました。

16
davetron5000

また、googlers ..の単純なルールでは、古い番号のバージョンを削除/編集しないでください。モデルバージョンを追加すると、番号のサフィックスが2..3..4のように増加します。これは、2が次に古い3などであることを意味します。ただし、編集する現在のバージョンは番号なしのバージョンです。

古いモデルバージョンを使用している以前のdbを使用しているユーザーは、古いスキーマと最新のスキーマを比較しないと、最新のdbモデルに移行できないため、古いモデルバージョンを削除しないでください。

11
Gmu

このGooglingに遭遇した人のためのメモですが、自動(マジック)マイグレーションでも、元のストアのバージョンと新しいストアを作成し、新しいバージョンを現在のバージョンとして設定する必要があるようです。

5
rustyshelf

これまでのところ、エラーメッセージを回避する方法のみを確認しています。

しかし、どうすれば修正できますか-すでに問題が発生した場合に備えて??

次の解決策問題は修正されましたが、データが失われます DB:

デプロイ/インストールされたアプリケーションのsqliteファイルの削除/名前変更
場所を示すファイルは、エラーメッセージの直後に表示されます。例えば。:

reason =ソースストアのモデルが見つかりません}、{
[〜#〜] url [〜#〜] = "file://localhost/Users/yourName/Library/Application%20Support/iPhone%20Simulator/4.3/Applications/62F342D4 -F007-4F6F-96D2-68F902D3719A/Documents/Locations.sqlite ";

1

軽量の移行を行う際に覚えておくべきこと-

属性の名前変更/変更を計画している場合は、新しいモデルまたは古いモデルのいずれかに「名前変更ID」の値を設定してください。 XCode 4.3でApple独自の例を使用するには、新しいモデルでpaintColorを選択し、Data Model Inspectorに切り替えて、[Versioning]セクションの[Renaming ID]フィールドをColorに設定します。私にとって、この手順を実行しないと、ランタイムエラーが発生しました。この同じエラーも ここで説明 です。新しいユーザーとして、私は画像を投稿することを許可されていないので、ここに 画像リンク (スパムではない)を示します。

    (Cocoa error 134140.)" UserInfo=0x622b350 {reason=Can't find or automatically infer mapping model for migration
1

このエラーは、データモデルに変更を加え、sqliteファイルのバージョンが異なるインストール済みアプリで実行した場合にも発生する可能性があります。この場合、インストールされているアプリを削除して再実行するだけです。

0
John Mead