IOSアプリプロジェクトを最近iOS 10に更新しました。アプリのコアデータモデルを変更しようとしていますが、Xcodeが生成する新しいNSManagedObjectサブクラスが壊れています。また、サブクラスのマニュアルを修正しようとしましたが、これは機能しません。
Core Data Modelの最小ツールバージョンはXcode 7.0に設定され、コード生成言語はSwiftに設定されます。
これは、Xcodeが生成するコードです。
import Foundation
import CoreData
import
extension Group {
@nonobjc public class func fetchRequest() -> NSFetchRequest {
return NSFetchRequest(entityName: "Group");
}
@NSManaged public var name: String?
@NSManaged public var platform: NSNumber?
@NSManaged public var profiles: NSOrderedSet?
}
// MARK: Generated accessors for profiles
extension Group {
@objc(insertObject:inProfilesAtIndex:)
@NSManaged public func insertIntoProfiles(_ value: SavedProfile, at idx: Int)
@objc(removeObjectFromProfilesAtIndex:)
@NSManaged public func removeFromProfiles(at idx: Int)
@objc(insertProfiles:atIndexes:)
@NSManaged public func insertIntoProfiles(_ values: [SavedProfile], at indexes: NSIndexSet)
@objc(removeProfilesAtIndexes:)
@NSManaged public func removeFromProfiles(at indexes: NSIndexSet)
@objc(replaceObjectInProfilesAtIndex:withObject:)
@NSManaged public func replaceProfiles(at idx: Int, with value: SavedProfile)
@objc(replaceProfilesAtIndexes:withProfiles:)
@NSManaged public func replaceProfiles(at indexes: NSIndexSet, with values: [SavedProfile])
@objc(addProfilesObject:)
@NSManaged public func addToProfiles(_ value: SavedProfile)
@objc(removeProfilesObject:)
@NSManaged public func removeFromProfiles(_ value: SavedProfile)
@objc(addProfiles:)
@NSManaged public func addToProfiles(_ values: NSOrderedSet)
@objc(removeProfiles:)
@NSManaged public func removeFromProfiles(_ values: NSOrderedSet)
}
編集:これらはXcodeが与える特定のエラーです:
1. Group+CoreDataProperties.Swift:13:1: Expected identifier in import declaration (the empty import)
2. Group+CoreDataProperties.Swift:13:11: 'Group' is ambiguous for type lookup in this context
3. Group+CoreDataProperties.Swift:15:16: Cannot specialize non-generic type 'NSFetchRequest'
4. Group+CoreDataProperties.Swift:26:11: 'Group' is ambiguous for type lookup in this context
4. Group+CoreDataProperties.Swift:43:82: 'SavedProfile' is ambiguous for type lookup in this context
私はついに私の仕事を得ました。これが私がしたことです。 (フライトは私のエンティティの1つです)
次のようにxcdatamodeldをセットアップします
そして、エンティティとして
次に、エディタ-> NSManagedObjectサブクラスの作成を使用しました
これにより、フライトエンティティの2つのファイルが作成されます
Flights + CoreDataProperties.Swift
フライト+ CoreDataClass.Swift
私はFlights + CoreDataClass.Swiftの名前をFlights.Swiftに変更しました
フライト。Swiftはただ
import Foundation
import CoreData
@objc(Flights)
public class Flights: NSManagedObject {
}
Flights + CoreDataProperties.Swiftは
import Foundation
import CoreData
extension Flights {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Flights> {
return NSFetchRequest<Flights>(entityName: "Flights");
}
@NSManaged public var ...
}
これは私にとってはうまくいくようです。
また、これは私にしばらく頭をかいてもらいました、そして、私はそれを援助として加えます。これを行うことができるFetchRequestの新しいGenericsバージョンを忘れないでください
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Flights")
NSManagedObjectサブクラスファイルを生成した後にこれらのエラーが発生した理由は、データモデルが変更されたときに選択されたCodegenオプションに関係していると思われます。
これはバグだとは思いません。少なくともXcode 8.1(8B62)にはありません。
同様の問題が発生し、Codegenオプションを「Manual/None」に変更し、Moduleオプションを「Global Namespace」のままにして修正しました。 NSManagedObjectサブクラスファイルを生成しました。ただし、状況によっては、NSManagedObjectサブクラスを生成する必要さえありません。
以下は、Appleのドキュメントのレビュー、Apple開発者フォーラム、および独自のプロジェクトでのテストに基づいたエンティティCodegenオプションの詳細です。
オプション1:「クラス定義」
これを「プラグアンドプレイ」オプションと考えてください
モデルエディターを使用して、Core Dataで管理するエンティティと関連属性を作成します。
NSMangagedObjectサブクラスジェネレーターは使用しないでください。必要なファイルは、Xcodeによって自動的に生成されます(ただし、プロジェクトナビゲーターには表示されません)。
NSManagedObjectファイルを生成する場合、Appleは、これらのファイルのヘッダーコメントでこれらのファイルを編集してはならないことを通知します。これらのファイルを編集する必要がある場合、これは別のCodegenオプションを使用する必要があることを示す良い兆候です。
エンティティのデフォルトのクラスオプションのままにします(モジュール=グローバルネームスペース、コード生成=クラス定義)
NSManagedObjectのメソッドをオーバーライドする必要がある場合は、Classオプションの下のNameを使用して拡張機能を作成できます。
// Optional extension in Entity.Swift extension Entity { // Override NSManagedObject methods }
オプション2:「手動/なし」
NSManagedObjectサブクラスファイルを表示および編集できることを除いて、オプション1と同様です。
モデルエディターを使用して、Core Dataで管理するエンティティと関連属性を作成します。
NSManagedObjectサブクラスジェネレーターを使用する前に、エンティティのCodgenオプションを「Manual/None」に設定します。 ModuleオプションはGlobal Namespaceである必要があります。
属性を追加/削除/更新した後、次の2つの選択肢があります。(1)生成されたNSManagedObjectファイルを手動で更新しますOR(2)NSManagedObjectサブクラスジェネレータを再度使用しますEntity + CoreDataProperties.Swiftファイル)。
繰り返しますが、NSManagedObjectのメソッドとメソッドをオーバーライドする必要がある場合は、拡張機能を作成できます。拡張は、Entity + CoreDataProperties.Swiftファイルではなく、Entity + CoreDataClass.Swiftファイルで作成する必要があります(このファイルは、モデルエディターの変更により更新される可能性があります)。
// Optional extension in Entity+CoreDataClass.Swift extension Entity { // Override NSManagedObject methods }
オプション3:「カテゴリ/拡張機能」
Core Dataで管理する必要のないカスタムプロパティがある場合は、このオプションを使用します。
モデルエディターを使用して、Core Dataで管理するエンティティと関連属性を作成します。
ModuleオプションがCurrent Product Moduleに設定され、Codegenオプションが「Category/Extension」に設定されていることを確認します。
自己管理するプロパティを使用して、独自のNSManagedObjectサブクラスを作成します。
NSMangagedObjectサブクラスジェネレーターは使用しないでください。必要なファイルは、Xcodeによって自動的に生成されます(ただし、プロジェクトナビゲーターには表示されません)。
// Subclass NSManagedObject in Entity.Swift class Entity: NSManagedObject { // Self managed properties }
// Optional extension in Entity.Swift extension Entity { // Override NSManagedObject methods }
これらの手順を試すことができます
それは仕事ですか?そうでない場合
すべてのclassがEntitiesと同じ名前でないことを確認してください。これらのクラスはBuild Phases-> Compile Sourcesにあります。重複している場合、クラスまたはエンティティの名前を変更します
または
プロジェクトフォルダーでこのコマンドを実行して、エラー情報を取得できます
xcodebuild -verbose
この問題が発生したときにこのメッセージが表示されました
シンボル_OBJC_CLASS _ $ _ RandomListの複製:
xxxx/RandomList.o
xxxx/RandomList + CoreDataClass.o
RandomList.hおよびRandomList + CoreDataClass.hは、コンパイル時に同じシンボルを持ちます
Xcodeが警告を出さなかったのに、コンパイラがエラーをスローすると思う
これがあなたを助けることを願っています
3番目のimport
ステートメントは空なので削除します。
注:これが発生する理由はわかりませんが、Xcode 8のバグだと思います。削除するだけで正常に機能します。
これはxcodeの問題で、xcodeがコアデータカテゴリクラスの間違った構文を生成するものだと思います。 1つのエンティティnsmanageobjectsubclass
に対してAgentDetails
を作成しています
ここで、xcodeはAgentDetails+CoreDataClass.h
およびAgentDetails+CoreDataClass.m
に誤ったコード構造を作成します。これらのコード構造は次のとおりです。
そして
AgentDetails.h
が同じインターフェイスを持っているため、インターフェイスの重複の問題が発生しています。
これを修正するには、AgentDetails+CoreDataClass.h
のコードを変更する必要があります
このようなAgentDetails+CoreDataClass.m
:
[データモデルインスペクター]で、[モジュール]の下の[現在の製品モジュール]および[コード生成]の下の[手動/なし]を選択します。 (これにより、サブエンティティファイルを編集し、同じエンティティで属性を変更したときにCoreDataProperties.Swiftを再生成できます。)
[エディタ]メニューで[NSManagedObjectSubclassの作成]を選択できます。 XcodeはYourEntity + CoreDataClass.SwiftとYourEntity + CoreDataProperties.Swiftの2つのファイルを作成します。最新のXcode(8.2.1)がない場合、モデルインスペクターで設定したオプション/非オプションのプロパティは正しく表示されません。 YourEntity + CoreDataProperties.Swiftファイルで編集できます。
また、NSManagedObjectサブクラスを自分で追加する場合は、次の手順に従うことを忘れないでください。「。xcdatamodeld」に移動->エンティティを選択->データモデルインスペクターを表示-> Codegen->「手動/なし」を選択
これは私のために働いた。
Xcode 8.1は内部でモデルクラスを生成しているようです。作成された2つのクラスを削除するだけで、コード内のエンティティを引き続き使用できます。
これは私が受け取っていたエラーメッセージです
<unknown>:0: error: filename "Recipe+CoreDataProperties.Swift" used twice: '/Users/Rick/Desktop/Devslop/Rick Recipe/Recipe+CoreDataProperties.Swift' and '/Users/Rick/Library/Developer/Xcode/DerivedData/Rick_Recipe-cctgjudvqobxlwetbcwmzrgxigwg/Build/Intermediates/Rick Recipe.build/Debug-iphonesimulator/Rick Recipe.build/DerivedSources/CoreDataGenerated/Rick_Recipe/Recipe+CoreDataProperties.Swift'
<unknown>:0: note: filenames are used to distinguish private declarations with the same name
Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc failed with exit code 1
私は以下の例を使って解決しました
作成CurrentcyPair.xcdatamodeld
CurrentcyPair.xcdatamodeldを選択し、デフォルトを選択-> エンティティ(CurrencyPair)、クラス(.ManagedCurrencyPair)
エンティティを選択し、インスペクターを開きます。データモデルのコード生成を手動/なしとして設定します
私はこれを見つけました David Atkinsonからの投稿 これは何らかの方法で役立ちます。 Davidが説明した方法でコードを生成した場合。いくつかの構文エラーのあるコードを取得しましたが、エラーを修正すると、すべてが以前のように機能します。 「。」で始まるファイルはありません。もう。
私が修正しなければならない構文エラーは-不必要なインポートです-そして私のコードで公開されることを意図していないいくつかの公開プロパティ
問題を解決する多くの答えを見ることができるが、ここで実際に起こっていることの背後にある本当の理由に欠けているので、私は一粒の塩を入れています。
私はこれとまったく同じ問題に出くわしましたが、簡単な調査を行うことで次のことがわかりました。
Xcode 7まで、コアデータエンティティのデフォルトの動作は、開発者が対応するNSManagedObjectサブクラスの変更を手動で作成および維持する必要があったことでした。 (これは、[Create NSManagedObject subclass ..]オプションを選択するエディターメニューを使用することで実現できます。).
Xcode 8以降、Appleは、NSManagedObjectサブクラスを管理および維持するためのCodegenという名前の新しい設定をData Model Inspectorに追加しました。この設定のデフォルト値は「クラス定義」です。これは、コンパイル時に定義済みのエンティティに基づいてNSManagedObjectサブクラスを生成し、派生データフォルダーに配置するようXcodeに指示します。
プロジェクト内にNSManagedObjectサブクラスとXcodeが自動的に生成するサブクラスがあると、管理オブジェクトモデルが重複しているため、「複数のコマンドが生成する...」コンパイル時エラーの背後にある本当の理由につながります!!!
解決策は、両方ではなく、どちらか一方を使用することです!私は個人的にプロジェクト内で管理オブジェクトモデルを使用することを好むため、この「Codegen」設定を「Manual/None」に変更しました。モデルにロジックを追加しない場合は、プロジェクトの管理オブジェクトモデルを削除して、Xcodeに上記の設定の「クラス定義」値に基づいて処理を実行させることもできます。これは、この問題に対処する正しい方法です。
このすべてを詳細に説明している素晴らしい記事をここで見つけることができます:
https://medium.com/@kahseng.lee123/core-data-codegen-explained-462c30341041
最新のXcode 8.1ベータ(8T47)ビルドを実行しています。
エラーログ(下記参照)によると、自動生成されたファイルの2つのコピーが作成されます。 1つのコピーはXcodeプロジェクトフォルダー(Xcodeの左側のツールバーのディレクトリに表示されます)に配置され、2つ目のコピーはプロジェクトのDerivedDataフォルダーに作成されます。
/Users/<your name>/Library/Developer/Xcode/DerivedData/<your app>-axhtnodotznxnrenefflktnxfeal/Build/Intermediates/<your app>.build/Debug-iphonesimulator/<your app>.build/DerivedSources/CoreDataGenerated/<your app>/<class name>+CoreDataProperties.Swift
/Users/<your name>/Library/Developer/Xcode/DerivedData/<your app>-axhtnodotznxnrenefflktnxfeal/Build/Intermediates/<your app>.build/Debug-iphonesimulator/<your app>.build/DerivedSources/CoreDataGenerated/<your app>/<class name>+CoreDataClass.Swift
Xcodeプロジェクトディレクトリのコピーを削除すると、すべての問題が修正されますが、これらのファイルを編集できなくなるため、意味がありません。
これは解決策とは言いませんが、むしろプロジェクトを構築するための半ばばかげた方法です。このバグがすぐに解決されることを願っています。
私にとっては、NSManagedObject
を手動でサブクラス化してCocoaTouchクラスを作成しました。モジュールをCurrent Product Moduleとして設定し、CodegenをCategory/Extensionとして設定すると、うまく機能します。
私の特定のケースでは、既存のプロジェクトにCoreDataを追加しましたが、このプロジェクトには既にエンティティと同じ名前のModelクラスがありました。古いModelクラスを削除すると、そのタイプが新しいCoreData Entityクラスと衝突するため、問題が修正されました。