XCode 8为iOS 10生成破坏的NSManagedObject子类
我最近更新了我的iOS应用程序项目到iOS 10.现在我试图改变我的应用程序的核心数据模型,但Xcode生成的新的NSManagedObject子类被打破。 我也试图修复子类手册,但这是行不通的。
核心数据模型的最低工具版本设置为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
我终于find了工作。 这是我做的。 (航class是我的一个实体)
我如下设置xcdatamodeld
然后是实体
然后我使用编辑器 – >创buildNSManagedObject子类
这为我的航class实体创build了两个文件
机票+ CoreDataProperties.swift
机票+ CoreDataClass.swift
我将Flights + CoreDataClass.swift改名为Flights.swift
Flights.swift只是
import Foundation import CoreData @objc(Flights) public class Flights: NSManagedObject { }
航class+ CoreDataProperties.swift是
import Foundation import CoreData extension Flights { @nonobjc public class func fetchRequest() -> NSFetchRequest<Flights> { return NSFetchRequest<Flights>(entityName: "Flights"); } @NSManaged public var ... }
这似乎对我有用。我不能让Codegen以任何其他方式工作,即使我尝试了很多的build议。
这也让我挠了一下头脑,并把它作为一个辅助。 不要忘记,新的generics版本的FetchRequest可以做到这一点
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Flights")
我相信你在生成NSManagedObject子类文件后遇到这些错误的原因可能与你的数据模型改变时select的Codegen选项有关。
我不认为这是一个错误。 至less不在Xcode 8.1(8B62)中。
我遇到了类似的问题,并通过将Codegen选项更改为“Manual / None”并将Module选项保留为“Global Namespace”来解决此问题。 然后我生成我的NSManagedObject子类文件。 但是,根据您的情况,您甚至可能不需要生成NSManagedObject子类。
下面是关于实体的Codegen选项的更多细节,基于我对苹果文档的审查,苹果开发者论坛和我自己的项目的testing。
选项1:“类定义”
-
把这看作是“即插即用”的select
-
使用模型编辑器来创build您想让Core Datapipe理的实体和关联属性。
-
不要使用NSMangagedObject子类生成器。 所需的文件是由Xcode为您自动生成的(但是它们不会显示在您的项目导航器中)。
-
如果您生成NSManagedObject文件,Apple会告诉您这些文件不应该在所述文件的标题注释中进行编辑。 如果你确实需要编辑这些文件,那么这是一个很好的标志,你需要使用另一个Codegen选项。
-
保留实体的默认类选项(模块=全局命名空间和Codegen =类定义)
-
如果您需要覆盖NSManagedObject的方法,则可以使用Class选项下的Name来创build扩展。
// Optional extension in Entity.swift extension Entity { // Override NSManagedObject methods }
选项2:“手动/无”
-
类似于选项1,不同之处在于您可以查看和编辑NSManagedObject子类文件。
-
使用模型编辑器来创build您想让Core Datapipe理的实体和关联属性。
-
在使用NSManagedObject子类生成器之前,请将实体的Codgen选项设置为“Manual / None”。 模块选项应该是全局命名空间。
-
添加/删除/更新属性后,有两个select:(1)手动更新为您生成的NSManagedObject文件或(2)再次使用NSManagedObject子类生成器(这将只更新实体+ CoreDataProperties.swift文件)。
-
同样,如果你需要覆盖NSManagedObject的方法,你可以创build一个扩展。 扩展应该在Entity + CoreDataClass.swift文件中创build,而不是Entity + CoreDataProperties.swift文件(由于模型编辑器的改变,这个文件可能会被更新)。
// Optional extension in Entity+CoreDataClass.swift extension Entity { // Override NSManagedObject methods }
选项3:“类别/扩展”
-
如果您的自定义属性不需要由Core Datapipe理,请使用此选项。
-
使用模型编辑器来创build您想让Core Datapipe理的实体和关联属性。
-
确保模块选项设置为当前产品模块,Codegen选项设置为“类别/扩展”。
-
用你自己pipe理的属性创build你自己的NSManagedObject子类。
-
不要使用NSMangagedObject子类生成器。 所需的文件是由Xcode为您自动生成的(但是它们不会显示在您的项目导航器中)。
// Subclass NSManagedObject in Entity.swift class Entity: NSManagedObject { // Self managed properties }
// Optional extension in Entity.swift extension Entity { // Override NSManagedObject methods }
-
要解决这个问题,请删除应用程序的派生数据。
-
然后将模块更改为当前产品模块,并将Codegen更改为手动/无 。
尝试设置CodeGen:手动/无模块:当前产品模块
当我遇到同样的问题时,它对我很有帮助。
删除第三个import
语句,因为它是空的。
注意:我不知道为什么发生这种情况,但我想这是Xcode 8中的一个错误。只要删除它,它就可以正常工作。
如果你有一个传统的应用程序,并且你希望手动添加托pipe对象类
- 确保核心数据模型codegen被设置为Manual / None
- select您的核心数据模型文件
- 创build托pipe对象的子类
你可以尝试这些步骤
- 在Xocde Project Navigator中select.xcdatamodeld文件
- 在数据模块检查器中 ,确保Codegen : Manual / None
- 然后编辑 – > 创buildNSManagedObject子类
- 清洁产品并重build
那是工作吗? 如果不
确保你所有的课都与实体不一样。 你可以在Build Phase – > Compile Sources中find这些类。 重命名类或实体,如果他们重复
要么
你可以在你的项目文件夹中运行这个命令来获得更多的错误信息
xcodebuild -verbose
当我有这个问题时,我得到了这个消息
重复的符号_OBJC_CLASS _ $ _ RandomList中:
XXXX / RandomList.o
XXXX / RandomList + CoreDataClass.o
RandomList.h和RandomList + CoreDataClass.h在编译时有相同的符号
我认为,为什么Xcode不警告你,但编译器会抛出错误
希望对你有帮助
我认为这是一个Xcode的问题,其中xcode生成核心数据类别类的错误语法。 我正在为一个实体AgentDetails
创build一个AgentDetails
这里xcode在AgentDetails+CoreDataClass.h
和AgentDetails+CoreDataClass.m
创build错误的代码结构。 那些代码结构如下所示:
和
因此, AgentDetails.h
具有相同的接口,因此具有重复的接口问题。
现在要解决这个问题,你必须改变AgentDetails+CoreDataClass.h
的代码
和AgentDetails+CoreDataClass.m
是这样的:
在Xcode 8.2.1上 ,我是这样做的:(谢谢Daniel Chepenko )
但Xcode 8.2.1会添加一个愚蠢的。 进入生成的文件:
只要删除。 它会正确运行。
在数据模型检查器中,select“模块”下的“当前产品模块”和“代码生成器”下的手动/无。 (这允许您编辑子类文件并在修改同一实体下的属性时重新生成CoreDataProperties.swift。)
然后你可以在Editor菜单下selectCreate NSManagedObjectSubclass。 Xcode将为您创build2个文件YourEntity + CoreDataClass.swift和YourEntity + CoreDataProperties.swift。 注意如果你没有最新的Xcode(8.2.1),你在Model Inspector中设置的任何可选/非可选属性将不能正确显示。 您可以在YourEntity + CoreDataProperties.swift文件中进行编辑。
Xcode 8.1似乎在内部生成模型类。 只要删除创build的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
我刚刚在我的模型中添加了一个Person实体到Core Data模板。 然后为此生成NSManagedObject子类,它不会编译,给我一个链接器错误。 原来,我应该更改Codegen选项为手动/无使其工作(请参阅图片的右下angular部分)。
我从大卫·阿特金森(David Atkinson)那里find了这篇文章,这在某些方面很有用 如果我用David描述的方式生成代码。 我只是得到了一些语法错误的代码,如果我修复了一切像以前一样工作的错误。 没有以'。'开始的缺失文件。 任何更多。
我必须纠正的语法错误是 – 不必要的导入 – 以及一些公开的属性,不打算在我的代码中公开
我正在运行最新的Xcode 8.1 beta(8T47)版本。
根据错误日志(见下面),创build两个自动生成的文件副本。 一个副本放在您的Xcode项目文件夹(Xcode左边的工具栏中的目录中可见的副本)中,并在您的项目的DerivedData文件夹中创build第二个副本:
/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项目目录中的副本将解决所有问题,但certificate毫无意义,因为您不能再编辑这些文件…
我不会说这是一个解决scheme,而只是半途而废的方式来build立项目。 希望这个错误将很快解决。
另外,如果你自己添加NSManagedObject子类,不要忘记按照以下步骤进行:转到'.xcdatamodeld' – >select实体 – >显示数据模型检查器 – > Codegen – >select'Manual / None'
这对我有效。
对我而言,我通过手动创buildNSManagedObject
的子类创build了CocoaTouch类。 我将模块设置为当前产品模块和Codegen作为类别/扩展,它运作良好。
你需要做的是CodeGen设置为Category / Extension,然后再执行Create NSManagedObject子类。
我有一个航class实体,这些设置在Data Model Inspector中为我工作:
-
将Name设置为空(您会看到一些灰色的“NSManagedObject”文本)。 默认会写成“Flights”,只是删除。
-
模块中没有任何东西,“全局命名空间”变灰是你将会看到的。
-
Codegen手动/无。
-
然后转到编辑器 – >创buildNSManagedObject子类来创buildswift文件
-
将Flights + CoreDataClass.swift重命名为Flights.swift
这里是截图的链接(出于某种原因imgur拒绝:() https://drive.google.com/file/d/0B8a3rG93GTRedkhvbWc5Ujl4Unc/view?usp=sharing
我改名后如下:
从:YourEntity + CoreDataClass.swift到:YourEntity.swift
和
从:YourEntity + CoreDataProperties.swift到:YourEntityCoreDataProperties.swift
那么它的工作。 它看起来像“+”是造成这个问题。