web-dev-qa-db-ja.com

NSManagedObjectの特定のサブクラスが見つかりません

Core Dataを使用したアプリの開発に取り組んでいます。次を使用してインスタンスを作成したとき:

let entity = NSEntityDescription.entityForName("User", inManagedObjectContext: appDelegate.managedObjectContext)
let user = User(entity: entity, insertIntoManagedObjectContext: appDelegate.managedObjectContext)

ログに警告が表示されました:

CoreData: warning: Unable to load class named 'User' for entity 'User'.  Class not found, using default NSManagedObject instead.

どうすれば修正できますか?

別の質問、NSManagedObjectサブクラスでインスタンスメソッドを定義するにはどうすればよいですか?

編集:

次のスクリーンショットのようにエンティティのクラスを指定しました:

enter image description here

131
MsrButterfly

Xcode 7(最終版)の更新:モジュール名をクラスの先頭に追加する(Xcode 6およびXcode 7の初期ベータリリースのように)必要はなくなりました。 Appleドキュメント Implementing Core Data Managed Object Subclasses は、それに応じて更新されました。

データモデルインスペクターには、エンティティの「クラス」と「モジュール」という2つのフィールドがあります。

enter image description here

エンティティのSwift管理オブジェクトサブクラスを作成すると、[モジュール]フィールドは[現在の製品モジュール]に設定され、この設定でインスタンスの作成はメインアプリケーションと単体テストの両方で機能します。管理対象オブジェクトのサブクラスは、not@objc(classname)でマークする必要があります(これは https://stackoverflow.com/a/31288029/1187415 )。

別の方法として、「モジュール」フィールドを空にして(「なし」と表示されます)、管理オブジェクトのサブクラスを@objc(classname)でマークできます(これは https://stackoverflow.com/a/31287260/1187415 )。


備考:この回答はもともとXcode 6向けに書かれたものです。この問題に関して、さまざまなXcode 7ベータリリースでいくつかの変更がありました。それは多くの賛成票とそれへのリンクを持つ受け入れられた答えなので、私は現在のXcode 7の最終バージョンの状況を要約しようとしました。

私は自分自身の「研究」を行い、この質問と同様の質問 CoreDataの両方に対するすべての答えを読みました:警告:named クラスをロードできません。したがって、特にリストに記載していなくても、帰属はそれらすべてに当てはまります!


Xcode 6の以前の回答:

Implementing Core Data Managed Object Subclasses で説明されているように、モデルエンティティインスペクターのClassフィールドのエンティティクラス名の前にモジュール名を付ける必要があります。たとえば、「MyFirstSwiftApp.User 「。

215
Martin R

サイドノートとして。私は同じ問題を抱えていました。そして、クラスファイルに@objc(ClassName)を追加するだけでした。

例:

@objc(Person)
class Person { }

そしてそれは私の問題を解決しました。

60
Christer

この質問に対する受け入れられた答えは、同じ問題を解決するのに役立ちましたが、他の人に役立つと思ったという警告がありました。プロジェクト(モジュール)名にスペースが含まれている場合は、スペースをアンダースコアに置き換える必要があります。例えば:

エンティティ:MyEntityクラス:My_App_Name.MyClass

30
Mannix

モジュールを忘れずに削除してください:

enter image description here

アプリ対テストとして実行しているかどうかによって、問題はアプリが<appName>.<entityName>を探していることと、テストとして実行しているときに<appName>Tests.<entityName>を探していることです。この時点で使用するソリューション(Xcode 6.1)は、CoreData UIのClassフィールドに入力せず、代わりにコードで入力することです。

このコードは、App vs Testとして実行されているかどうかを検出し、正しいモジュール名を使用してmanagedObjectClassNameを更新します。

lazy var managedObjectModel: NSManagedObjectModel = {
    // The managed object model for the application. This property is not optional...
    let modelURL = NSBundle.mainBundle().URLForResource("Streak", withExtension: "momd")!
    let managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL)!

    // Check if we are running as test or not
    let environment = NSProcessInfo.processInfo().environment as [String : AnyObject]
    let isTest = (environment["XCInjectBundle"] as? String)?.pathExtension == "xctest"

    // Create the module name
    let moduleName = (isTest) ? "StreakTests" : "Streak"

    // Create a new managed object model with updated entity class names
    var newEntities = [] as [NSEntityDescription]
    for (_, entity) in enumerate(managedObjectModel.entities) {
        let newEntity = entity.copy() as NSEntityDescription
        newEntity.managedObjectClassName = "\(moduleName).\(entity.name)"
        newEntities.append(newEntity)
    }
    let newManagedObjectModel = NSManagedObjectModel()
    newManagedObjectModel.entities = newEntities

    return newManagedObjectModel
}()
9
Ludovic Landry

プロジェクト名に「My-App」などのハイフンを使用している場合は、「My_App.MyManagedObject」などのハイフンの代わりにアンダースコアを使用します。一般に、xcdatamodeldファイルの名前を見て、その名前と同じプレフィックスを使用します。つまり「My_App_1.xcdatamodeld」には接頭辞「My_App_1」が必要です

8
Rien

これは、同じ問題が発生している人に役立つ場合があります。私は、Swift 2とXcode 7ベータ2でした。

解決策 私の場合、EntityName.Swift@objc(EntityName)をコメントアウトすることでした。

5
enreas

私のアプリは正常に動作しているように見えましたが、同じ警告が表示されました。問題は、最後の画面で[エディター]> [NSManagedObjectサブクラスの作成]を実行するときに、ターゲットが表示またはチェックされていないデフォルトのグループの場所を使用したことです。
代わりにグループをMyAppサブフォルダーに変更し、MyAppターゲットをチェックすると、警告は消えました。

3
Daniel Ford

ちなみに、接頭辞として追加するものには注意してください。私のアプリは「ABC-def」と呼ばれ、Xcodeは「-」を「_」に変換しました。

Finderを安全に見るために、プロジェクトファイルを見つけて、データモデル(たとえば、「ABC_def.xcdatamodeld」)の内容を確認し、そこに書かれているものを正確に使用してください!!!

2
Mike

上記の回答は役に立ちました。この簡単な健全性チェックにより、時間を節約できます。 [プロジェクト]> [ビルドフェーズ]> [ソースのコンパイル]に移動し、[-]ボタンでxcdatamodeldとモデルファイルを削除してから、[+]ボタンで元に戻します。再構築-それはそれを大事にするかもしれません。

2
trevorgrayson

上記の答えは、Objective-Cに関連するさまざまな問題を解決するのに役立ちました(誰かを助けるかもしれません)。

エンティティ名をリファクタリングした場合、「ユーティリティパネル」の「クラス」も変更することを忘れないでください。

1
Vive

上記の答えは私を助けましたが、これは誰かを助けるかもしれません。私のようにあなたがそれらをやったがまだ問題がある場合は、単に「プロジェクトをきれいにする」ことを忘れないでください。 XCode8の場合、[製品]> [クリーン]。その後、再度実行してください。

0
Olaolu Akinsete

Xcode 7では、エンティティ名とクラス名は同じでもかまいませんが、Codegenはクラス定義でなければなりません。その場合、警告などはありません。 ここに画像の説明を入力してください

0
dcaric