私は自分のアプリの特定の部分をフレームワークに移行して、自分のアプリ自体とそれらの豪華な新しいiOS 8ウィジェットの1つで使用できるようにしています。この部分は、Core Data内のすべてのデータを処理する部分です。すべてを移動してアクセスするのは簡単です。そこにあるmomd
ファイルへのアクセスに問題があります。
NSManagedObjectModel
を作成するときも、Appleのコードテンプレートに示されているように、momd
をロードしようとします。
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyApp" withExtension:@"momd"];
__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
残念ながら、modelURL
はnil
のままなので、このエラーでCore DataスタックにアクセスするとMyApp
がクラッシュします。
2014-08-01 22:39:56.885 MyApp[81375:7417914] Cannot create an NSPersistentStoreCoordinator with a nil model
2014-08-01 22:39:56.903 MyApp[81375:7417914] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Cannot create an NSPersistentStoreCoordinator with a nil model'
それで、Core Dataを使用してフレームワーク内で作業するときにこれを行う正しい方法は何ですか?
私はfloheiの問題に少し遅れますが、うまくいけば、これが他の人が迷うのを助けるでしょう。これを機能させるには、script-fuを実行してリソースをコピーする必要はありません。
デフォルトでは、Appleのコアデータテンプレートは次のようなものを提供します。
lazy var managedObjectModel: NSManagedObjectModel = {
let modelURL = NSBundle.mainBundle().URLForResource("MyCuteCoreDataModel", withExtension: "momd")!
return NSManagedObjectModel(contentsOfURL: modelURL)!
}()
これにより、メインバンドルからコアデータリソースが読み込まれます。ここで重要なのは、Core Dataモデルがフレームワークにロードされている場合、。momdファイルはそのフレームワークのバンドルにあるです。したがって、代わりにこれを行うだけです。
lazy var managedObjectModel: NSManagedObjectModel = {
let sexyFrameworkBundleIdentifier = "com.heybaby.xxx"
let customKitBundle = NSBundle(identifier: sexyFrameworkBundleIdentifier)!
let modelURL = customKitBundle.URLForResource("MyCuteCoreDataModel", withExtension: "momd")!
return NSManagedObjectModel(contentsOfURL: modelURL)!
}()
これで問題なく動作するはずです。
クレジット: https://www.andrewcbancroft.com/2015/08/25/sharing-a-core-data-model-with-a-Swift-framework/
Xcdatamodeldファイルをドラッグして、ビルドフェーズにドロップする必要があります。フレームワークを使用するターゲットのソースをコンパイルします。次に、ターゲットを実行すると、その[NSBundle mainBundle]にモデル(momdファイル)が含まれます。
@Ric Santosはほとんどそこにいた。私はそれを「momd」ではなく「mom」拡張にするだけで十分だと思います。そうすれば実行されます。
lazy var managedObjectModel: NSManagedObjectModel = {
let modelURL = NSBundle(forClass: self.dynamicType.self).URLForResource(self.dataModelName, withExtension: "mom")!
return NSManagedObjectModel(contentsOfURL: modelURL)!
}()
私はこれに答えるのが少し遅れるかもしれませんが、これが私の問題を解決したものです:
私のフレームワークでは、画像やその他のリソースなどのバンドルも提供しています。 xcdatamodeldファイルを置くと、このファイルがプロジェクトでビルドされるため、何も得られず、結果としてアプリバンドル内のmomdフォルダー(実際にはこのケースにはありません)。別のターゲットを作成しましたが、フレームワークではなく、アプリを作成し、アプリバンドルからmomdをコピーしました。プロジェクト内の別のバンドル(フレームワークに対応するもの)。これを行った後は、リソースのURLをメインバンドルから新しいバンドルに変更するだけです。
// ...
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"separate_bundle" ofType:@"bundle"];
NSURL *modelURL = [[NSBundle bundleWithPath:bundlePath] URLForResource:@"your_model" withExtension:@"momd"];
// ...
私にとってはうまくいきました。私が知っている唯一のことは、まだ知らなかったApp Store Reviewです。より良い解決策を見つけた場合は、共有してください。
[〜#〜]編集[〜#〜]
より良いソリューションが見つかりました。自分でモデルを作成できます。 コアデータプログラミングガイド :
データモデルはデプロイメントリソースです。モデルのエンティティとプロパティの詳細に加えて、Xcodeで作成するモデルには、ダイアグラムに関する情報(レイアウト、要素の色など)が含まれています。この後者の情報は、実行時には必要ありません。モデルファイルは、モデルコンパイラーmomcを使用してコンパイルされ、無関係な情報を削除し、リソースの実行時の読み込みをできるだけ効率的にします。 xcdatamodeldの「ソース」ディレクトリはmomdデプロイメントディレクトリにコンパイルされ、xcdatamodelの「ソース」ファイルはmomデプロイメントファイルにコンパイルされます。
momcは/ Developer/usr/bin /にあります。独自のビルドスクリプトで使用する場合、その使用法はmomcソース宛先です。ここで、ソースはコンパイルするCore Dataモデルのパスであり、宛先は出力のパスです。
「/ Developer/usr/bin /」とは、「/ Applications/Xcode.app/Developer/usr/bin /」を意味します
ターゲットスキームにスクリプトを追加して、各ビルドの前に(または重要ではないと考えてから)これを自動的にコンパイルできます。開発中にモデルを変更した場合に備えてください。
このようなもの:
mkdir -p "${BUILT_PRODUCTS_DIR}/your_model_name.momd"
momc "${SRCROOT}/your_model_path/your_model_name.xcdatamodeld" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.framework/your_bundle_name.bundle/your_model_name.momd"
モデルリソースにはmainBundle
からアクセスできなくなりました。次のようにbundleForClass:
を使用する必要があります。
NSURL *modelURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"MyApp" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
フレームワークにコアデータを含めようとする場合は、次のようにします。
yourFrameworkで-新しいファイル/コアデータ/データモデルを追加...-すべてのオブジェクトを作成...
YourFrameworkを使用する新しいプロジェクトを作成するときは、コアデータがオンになっていることを確認してください
これにより、AppDelegate内にすべてのボイラープレートが作成されます。
テストプロジェクトで-フレームワークを追加-フレームワークを埋め込みフレームワークとして追加-DELETE .xcdatamodeldファイル-AppDelegateで:
- (NSManagedObjectModel *)managedObjectModel
メソッドを次のように変更します。
NSBundle * testBundle = [NSBundle bundleWithIdentifier:@"YourFramework bundle id "];
NSURL *modelURL = [testBundle URLForResource:@"Model" withExtension:@"momd"];
どこ YourFramework bundle id
はYourFrameworkのバンドルIDです(一般/バンドルID)
Model
はYourFramework内の.xcdatamodeldファイルの名前です
これは機能します。
それが役に立てば幸い。
データモデルのみが必要だと思います。
もしそうなら、私は一貫して、あるプロジェクトから別のプロジェクトにデータモデルファイル全体をコピーするための最も成功した方法を見つけます...
.xcdatamodeld
ファイルの現在のコピーをすべて削除します。Xcodeを閉じます。
Finder(またはcmd行)を使用する。
.xcdatamodeld
ファイルを含むXcodeプロジェクトフォルダーを選択します。.xcdatamodeld
ファイルのコピーを作成します。元の.xcdatamodeld
ファイルのコピーをターゲットプロジェクトに移動します。
その後...
.xcdatamodeld
ファイルのコピーを見つけ、プロジェクトに追加します。.xcdatamodeld
ファイルの名前を変更します(必要な場合)。これは役に立ちますか?