1

iOS アプリと iOS クライアントが通信するサーバーの両方で使用している CoreData ベースのデータ レイヤー (SQLite データストアを使用) があります。データ層 (objc コード + coredata モデル / マッピング定義) は、通常どおり iOS バンドルにコンパイルされ、OSX で使用するためのフレームワーク バンドルにコンパイルされます。

マッピング モデルを使用したデフォルトの移行で壁にぶつかっています。

iOSでは、問題なく動作します。新しいデータモデル バージョンを追加した後、初めてシミュレーターでアプリを実行するとaddPersistentStoreWithType:configuration:...、標準の Apple ドキュメントに従って呼び出すと、すべてのデータが移行されます。

OSX / PyObjC では、 で失敗しますPersistent store migration failed, missing mapping model。つまり、なんらかの理由で、マッピング モデル .cdm ファイルがそのバンドル内に存在していても見つかりません。

ソース/宛先/マッピング モデルをバンドルで検索して手動で指定し、NSMigrationManager を介して手動で移行を呼び出すと、すべて正常に動作します。

bundle = objc.loadBundle( "MyApp_OSX", globals(),
                          os.path.join( base, FRAMEWORK_FILENAME ) )

# URLs of input and output datastores
datastoreURL = NSURL.fileURLWithPath_( datadir + "/MyApp.hsdb" )
outURL = NSURL.fileURLWithPath_( datadir + "/MyApp-migrated.hsdb" )

# URLs of old and new version MOMs and the mapping model
momd = bundle.URLForResource_withExtension_( "MyApp.momd", None )
url1 = momd.URLByAppendingPathComponent_( "MyApp 21.mom" )
url2 = momd.URLByAppendingPathComponent_( "MyApp 22.mom" )
mappingURL = bundle.URLForResource_withExtension_( "Test.cdm", None )

# Old and new MOMs and the mapping model
mom1 = NSManagedObjectModel.alloc().initWithContentsOfURL_( url1 )
mom2 = NSManagedObjectModel.alloc().initWithContentsOfURL_( url2 )
mm = NSMappingModel.alloc().initWithContentsOfURL_( mappingURL )

# Do the migration    
migration = NSMigrationManager.alloc().initWithSourceModel_destinationModel_( 
    mom1, mom2 )

migration.migrateStoreFromURL_type_options_withMappingModel_toDestinationURL_destinationType_destinationOptions_error_(
    datastoreURL, NSSQLiteStoreType, None, mm, outURL, NSSQLiteStoreType, None, None )

この時点で、iOS バージョンがマッピング モデルを見つけてデータストアを正常に移行できる理由がわかりませんが、バンドルにマッピング モデルが明確にあり、マッピング モデルが明らかに有効であるにもかかわらず、OSX / PyObjC バージョンではそれができません。手動で呼び出すと機能するためです。

CoreData がバンドル内の有効/適切なマッピング モデルを検索する方法についての洞察は、OSX でこれを機能させる方法を特定するのに役立ちます。

4

1 に答える 1

1

これは iOS と Cocoa が異なる領域の 1 つであるため、パーミッションの問題が疑われますが、ハード コーディングされた URL が機能するため、そうではありません。NSBundleの問題のようです。

の標準形式を使用して開始しURLForResource:withExtension:、名前と拡張子を分割します。おそらく原因ではありませんが、ブリッジが完全ではないため、考えられるソース エラーを排除したいと考えています。

バンドル内にファイルが存在することを確認したら、次にそのファイルのパスが適切であることを確認します。ネストが深くなったり、パス名に奇妙な文字が含まれたりすると、NSBundle がファイルを見つけられない場合があります。

于 2010-09-07T16:48:43.903 に答える