Xcode 8中的Core Data Codegen失败

17
我有一个iOS应用程序,其中包含一个Core Data模型和6个实体。实体Name设置如下:

类名:Name

模块:当前产品模块

代码:类定义

(其他5个实体也类似设置)。 问题1(已自行解决但留给纪念)
代码确实生成在派生数据文件夹中... 不是预期的类定义,而是作为扩展(命名为 Name+CoreDataProperties.swift)。无论Codegen设置为Class Definition还是Category/Extension都没有关系 - 我仍然得到相同的结果。 好了,把这个想法放在一旁 - 突然间类和扩展文件都被生成了...看起来你需要在更新之间删除项目的派生数据文件夹并重新启动Xcode。忽略问题1。 问题2 生成的文件忽略了数据模型可选标志设置为字符串属性和关系 - 它们都被生成为可选项。 问题3(已自行解决但留给纪念)
有序关系被生成为OrderedSet(一个编译错误),而不是NSOrderedSet(无法更改它们,因为它们会被重新生成)。
对我来说,解决方法是暂时添加到项目中... public typealias OrderedSet = NSOrderedSet 好了,现在编译器错误已经消失,而且OrderedSet似乎被识别了。忽略问题3。 问题4 上述所有问题都不重要,因为编译器找不到它刚刚生成的文件。针对上面的Name实体:

:0:错误:没有这样的文件或目录:

'/Users/ashleymills/Library/Developer/Xcode/DerivedData/-grfqveelvqtlydbpwjmfdietnrss/Build/Intermediates/.build/Debug-iphonesimulator/.build/DerivedSources/CoreDataGenerated//.Name+CoreDataClass.swift' :0: 错误:没有找到文件或目录:'/Users/ashleymills/Library/Developer/Xcode/DerivedData/-grfqveelvqtlydbpwjmfdietnrss/Build/Intermediates/.build/Debug-iphonesimulator/.build/DerivedSources/CoreDataGenerated//.Name+CoreDataProperties.swift'

它正在派生数据中查找文件 .Name+CoreDataClass.swift.Name+CoreDataProperties.swift - 请注意文件名前面的点号。 (作为临时解决办法,我将生成的文件添加到了项目中)

我认为我做错了什么,因为如果对于每个人都是这样的情况,那么没有人能构建Core Data项目...还是说这些需要提出的错误?

感谢 Ash

(也在Apple开发者论坛上提出)


我在我的一个项目中遇到了同样的问题4,你解决了这个问题还是继续使用解决方法?你有苹果开发者论坛上同样问题的链接吗? - Bocaxica
6个回答

11

关于问题1,在.xcdatamodel中为实体设置检查器中的Codegen弹出窗口应该按如下方式工作:

类别/扩展告诉Xcode生成一个文件,ClassName+CoreDataGeneratedProperties。

类定义告诉Xcode生成两个文件,上述命名的文件,加上ClassName+CoreDataClass。

然而,在Xcode 8.2存在一个错误。如果在更改其中一个这些弹出窗口后,您仅构建(⌘B)或运行(⌘R),则您的更改将不会生效。例如,如果您从类定义更改为类别/扩展,甚至手动删除了第二个文件,它也会重新出现。您甚至可能发现弹窗回到了原始设置。

为了使这些弹出窗口中的更改生效,您必须:

  1. 保存(⌘S).xcdatamodel文件。
  2. 关闭所有项目窗口。
  3. 重新打开项目。

在下一次构建期间(如果故事板中有@IBInspectable,则可以在项目打开时自动发生),Derived Data中受影响的文件将生成或删除以符合您的新设置。

更新2016-12-22:感谢您的评论,Ashley。我现在已经将此提交给Apple错误报告:29789727。更新2017-02-08:苹果关闭了29789727,因为它据说重复了21205277。


是的 - 这个问题自8.0版本以来就一直存在。我通常最终会编辑.xcdatamodel内容的原始xml。 - Ashley Mills
当我选择“类定义”时,我在哪里可以找到扩展文件,以便我可以添加包括处理瞬态属性的自己的方法? - Satyam
@Satyam,这是一个好问题,但与此问题无关。此外,答案太长且复杂,无法在评论中概括。请提出一个新问题进行询问。 - Jerry Krinock
它把文件名和导入语句都搞错了,真是一团糟! - malhal

6

问题4可以在最新的测试版v.6中解决,方法是选择所有您想要自动生成的实体,然后在检查器中清除Class-> Module字段,使其默认为“全局命名空间”。


2
关于问题2:Core Data中的“可选”标志与Swift中的可选概念无关,它们是不相关的且意义不同。将Core Data属性标记为非可选并不意味着它在Swift中定义的术语下也是非可选的。它们的区别在于:
  • Swift中的非可选项必须始终具有非nil值。
  • Core Data中的非可选项必须在保存更改时具有非nil值,但Core Data不知道也不关心它们在其他时间是否为nil。
问题#4似乎是Xcode混淆了其状态,可以通过像手动清除派生数据文件夹这样的巫术来解决(我知道这很烦人)。我目前无法复现它,但这并不意味着它不是当前测试版中的错误。

1
我理解Core Data和Swift中可选项的区别,但我不明白为什么具有默认值的非可选属性不会生成为具有默认值的非可选属性...它仍然是一个Swift可选项。那么,当我们知道它们有值时,我们应该如何处理可选项?(因为Core Data的非可选项+默认值)。我们是否应该在使用托管对象属性的每个方法中保护自己以检查该值是否为空? - alpennec
我同意并建议向Apple提交错误报告。目前,要么(a)将属性更改为Swift非可选项,要么(b)即使您知道有值,也将其视为Swift可选项。我知道这两者都不理想。 - Tom Harrington
关于(a),我正在使用Xcode 8自动生成NSManagedObjects的子类。因此,我无法控制生成的临时类和扩展:默认情况下是可选的,我无法更改它(就我所知)...所以我现在会坚持使用(b),并考虑向Apple报告一个错误。 - alpennec

1
看起来 Xcode 8.2.1 无法关闭代码生成。 但你可以手动从 .xcdatamodel 内容文件中删除 codeGenerationType="category"
关闭 Xcode,删除 codeGenerationType,删除 DerivedData 文件夹并重新构建。
将等待未来版本的修复。

1
我完全卡在了问题4上,以上的解决方法对我都没有用。我使用代码生成。为了解决这个问题,我采取了以下步骤:
  1. 我在文本编辑器中打开了.xcdatamodel / content文件。(在Xcode中右键单击您的.xcdatamodel并选择“在外部编辑器中打开”)
  2. 在XML文件中,我确保每个实体都有codeGenerationType="class"
  3. 关闭并重新打开Xcode,清除我的派生数据文件夹
  4. 它仍然拒绝进行代码生成,因此我手动生成了每个实体(编辑器,创建NSManageObject子类,选择所有实体)
  5. 构建项目。现在它也进行了代码生成,并出现编译器错误,说实体文件名被两次使用。
  6. 删除步骤5中手动创建的NSManagedObject子类。
  7. 之后,项目再次成功构建,问题消失了。
PS:如果您选择手动创建NSManageObject子类而不是使用代码生成,请确保在步骤2中从XML文件中删除codeGenerationType="class"

1

实际上很容易修复它。

进入配置:

enter image description here

然后删除这些点。这些只存在于旧项目中。 在此之后,导入语句已经修复,您可以开始使用了。

您还应该将模型放置在全局命名空间中。我的模型位于额外的命名空间中,但我不知道为什么。

苹果的方法是您可以在自定义框架中使用此功能。

如果您能让它工作,这个功能非常好用;)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接