【问题标题】:Generating Swift models from Core Data entities从 Core Data 实体生成 Swift 模型
【发布时间】:2014-07-23 18:57:31
【问题描述】:

Xcode 8 更新:

在 Xcode 8 中,需要进入核心数据模型编辑器并显示文件检查器。靠近底部的是代码生成选项。选择斯威夫特。

编辑:我找到了从 Core Data 实体生成 Swift 模型的解决方案:

在 Xcode 上:

编辑器 > 创建 NSManagedOjbect > 单击“下一步”按钮 > 单击“下一步”按钮 > 选择“Swift”语言 > 单击“创建”按钮


我通过使用 Core Data 在 Xcode 6 beta 上创建一个新的 Swift 项目来尝试 Swift 语言。

当我从 Core Data 的实体生成模型时,Xcode 会创建 Objective-C 模型。

有没有办法使用 Core Data 生成 Swift 模型而不是 Obejctive-C 模型?

谢谢!

【问题讨论】:

    标签: xcode core-data model swift nsmanagedobject


    【解决方案1】:

    让我们看看Objective-C的方式:

    Person.h(头文件)

    #import <Foundation/Foundation.h>
    #import <CoreData/CoreData.h>
    
    @interface Person : NSManagedObject
    @property (nonatomic, retain) NSString *name;
    @end
    

    Person.m(实施文件)

    #import "Person.h"
    
    @implementation Person
    @dynamic name;
    @end
    

    斯威夫特

    Xcode6-Beta 中已经包含的文档说:

    Core Data 在 NSManagedObject 类的子类中提供底层存储和属性实现。在托管对象子类中与核心数据模型中的属性或关系相对应的每个属性定义之前添加 @NSManaged 属性。与 Objective-C 中的 @dynamic 属性一样,@NSManaged 属性通知 Swift 编译器,属性的存储和实现将在运行时提供。但是,与@dynamic 不同,@NSManaged 属性仅适用于 Core Data 支持。

    这就是我将如何为 Swift 重写上面的示例(未测试):

    Person.swift

    import CoreData
    
    class Person: NSManagedObject {
    
        @NSManaged var name : NSString
    
    }
    

    根据您的问题,我认为子类生成功能可能尚未包含在 Xcode6 中。在 Xcode 中创建 Cocoa-Project 时,您确定选择了“Swift”作为编程语言吗?

    【讨论】:

    • 感谢您的回答,是的,我检查了,我在创建项目时选择了 Swift 语言。
    • 是的,我可以确认这个版本的 Xcode 中不包含 swift 的子类生成功能。
    • import Cocoa 为我生成了错误“没有这样的模块 'cocoa'”。我把它切换到import CoreData,它对此很满意。
    • 注意:要使用这个例子,你必须在课堂前加上@objc(Person)。否则,任何访问 Person 实例的尝试都将导致崩溃。感谢您的回答!
    • 仅供参考,Xcode 6 beta 3 允许自动创建托管对象子类(尽管令人讨厌的是默认是 Objective-C,即使在 Swift 项目中也是如此)
    【解决方案2】:

    您可以使用 NSEntityDescription.insertNewObjectForEntityForName 恢复 Swift 模型,但您必须编辑核心数据模型文件,而不是使用 Person 作为类实体,而是使用 &lt;ProjectName&gt;.Person 否则它返回 NSManagedObject...

    使用println(),您不会看到Person 实例,但会看到&lt;_TtC5ProjectName4Person: 0xc9ad5f0&gt; 之类的东西,但在此调用方法将证明它是真实的Person 实例。我想这只是 Swift 生成唯一类名的方式,而不是冲突,CoreData 方法显示了这种内部机制。

    Apple documentation says:

    Swift 类是命名空间的——它们的作用域是编译它们的模块(通常是项目)。要将 NSManagedObject 类的 Swift 子类与您的 Core Data 模型一起使用,请在具有模块名称的模型实体检查器。

    【讨论】:

    • Arg 让我难过...这是否记录在任何地方?我觉得这可能会在发布前改变
    • 我使用这种方法 - 用项目名称装饰类名 - 这适用于运行应用程序,但我使用核心数据的测试会抛出无效的强制转换方法。有什么解决方法吗?
    • @DanielD 您是否在测试目标中找到了铸造问题的解决方案?因为这就是我现在正在努力解决的问题......
    • @Fabien Penso 你能在 Github 上创建示例项目吗?
    【解决方案3】:

    根据 Apple 关于 CoreData 框架中的新增功能:38 分钟(WWDC2014 Session 225)的视频,在检查员的数据模型中,在类名称前加上项目名称。喜欢 projectName.Doctor

    我已经尝试过了,但是会发生的是生成的托管对象类变为:projectName.swift 而不是 Doctor.swift。甚至类声明也变成了class projectName: ManagedObject

    解决方案:

    在数据模型检查器中,只需将对象的名称和类指定为您想要的名称,例如:医生

    在您生成对象模型并选择 Swift 后,这将创建一个文件 (Doctor.swift)。

    现在,在 Core Data 中插入新记录时,即使您将新插入的对象转换为正确的对象名称,您也可能会遇到错误“找不到类,而是使用默认的 NSManagedObject”

    要解决这个问题,您只需在类声明上方添加@objc(class name)。请参阅下面的示例。

    import Foundation
    import CoreData
    
    @objc(Doctor)
    class Doctor: NSManagedObject {
        @NSManaged var name: String
    }
    

    然后:

    let doctorManagedObject = NSEntityDescription.insertNewObjectForEntityForName("Doctor", inManagedObjectContext: context) as Doctor
    doctorManagedObject.name = "John" // you can now use dot syntax instead of setValue
    

    保存上下文以提交插入。

    【讨论】:

    • 保存上下文以提交插入将是 context.save(nil)
    • @objc(Doctor) 实际上做了什么?
    • @objc(Doctor) 表示您将Doctor类的声明暴露给Objective-C。
    【解决方案4】:

    我测试了@NSManaged,它没有用。 :( 。 但是由xcdatamodel生成的混合模型文件(.h),它成功了。 请阅读https://github.com/iascchen/SwiftCoreDataSimpleDemo中的文档和代码

    【讨论】:

    【解决方案5】:

    或者,您可以将 #import "Person.h" 添加到 Xcode 为您生成的桥接头 Project-Bridging-Header.h(如果您接受了生成的提议)。然后你就可以像使用原生 Swift 一样使用所有自动生成的 Obj-C。

    【讨论】:

      【解决方案6】:

      Editor -> Create NSManagedObject Subclass 适用于 Swift

      只需完成所有常规步骤,但是当您开始创建文件时,如果您是第一次使用 Create NSManagedObject Subclass 和 Swift 项目,请选择语言“Swift”将默认为 Objective C

      【讨论】:

        【解决方案7】:

        适用于 XCode 12。

        您可以更改生成模型语言。

        【讨论】:

          猜你喜欢
          • 2020-07-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-02-22
          • 1970-01-01
          • 2017-03-15
          • 2017-05-06
          相关资源
          最近更新 更多