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 }

  1. 要解决这个问题,请删除应用程序的派生数据。

  2. 然后将模块更改为当前产品模块,并将Codegen更改为手动/无

  3. 项目清单

尝试设置CodeGen:手动/无模块:当前产品模块

当我遇到同样的问题时,它对我很有帮助。

在这里输入图像说明

删除第三个import语句,因为它是空的。

注意:我不知道为什么发生这种情况,但我想这是Xcode 8中的一个错误。只要删除它,它就可以正常工作。

如果你有一个传统的应用程序,并且你希望手动添加托pipe对象类

  1. 确保核心数据模型codegen被设置为Manual / None
  2. select您的核心数据模型文件
  3. 创build托pipe对象的子类

编辑器的截图

你可以尝试这些步骤

  1. 在Xocde Project Navigator中select.xcdatamodeld文件
  2. 数据模块检查器中 ,确保CodegenManual / None
  3. 然后编辑 – > 创buildNSManagedObject子类
  4. 清洁产品并重build

那是工作吗? 如果不

确保你所有的都与实体不一样。 你可以在Build Phase – > Compile Sources中find这些类。 重命名类或实体,如果他们重复

要么

你可以在你的项目文件夹中运行这个命令来获得更多的错误信息

xcodebuild -verbose

当我有这个问题时,我得到了这个消息

重复的符号_OBJC_CLASS _ $ _ RandomList中:

XXXX / RandomList.o

XXXX / RandomList + CoreDataClass.o

RandomList.hRandomList + CoreDataClass.h在编译时有相同的符号

我认为,为什么Xcode不警告你,但编译器会抛出错误

希望对你有帮助

我认为这是一个Xcode的问题,其中xcode生成核心数据类别类的错误语法。 我正在为一个实体AgentDetails创build一个AgentDetails 它正在创建以下类

这里xcode在AgentDetails+CoreDataClass.hAgentDetails+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中为我工作:

  1. 将Name设置为空(您会看到一些灰色的“NSManagedObject”文本)。 默认会写成“Flights”,只是删除。

  2. 模块中没有任何东西,“全局命名空间”变灰是你将会看到的。

  3. Codegen手动/无。

  4. 然后转到编辑器 – >创buildNSManagedObject子类来创buildswift文件

  5. 将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

那么它的工作。 它看起来像“+”是造成这个问题。