Swift:使用枚举在CoreData中存储状态

kev*_*kev 44 core-data swift

我想在CoreData中为托管对象存储枚举状态

enum ObjStatus: Int16 {
    case State1 = 0
    case State2 = 1
    case State3 = 3
}

class StateFullManagedObject: NSManagedObject {
    @NSManaged var state: Int16
}
Run Code Online (Sandbox Code Playgroud)

最后一步是将StateFullManagedObject的状态变量转换为ObjStatus以进行直接比较,这对我不起作用.例如,我不能在Int16和Int16枚举之间使用==运算符.我得到的编译时错误是

Int16无法转换为'MirrorDisposition'

.见下面的条件:

var obj: StateFullManagedObject = // get the object

if (obj.state == ObjStatus.State1) { // Int16 is not convertible to 'MirrorDisposition'

}
Run Code Online (Sandbox Code Playgroud)

如何在Int16和枚举之间进行比较/分配?

Mar*_*nek 71

您可以将枚举声明为@objc.然后它全部自动化.这是我正在研究的项目的片段.

// Defined with @objc to allow it to be used with @NSManaged.
@objc enum AgeType: Int32
{
    case Age                = 0
    case LifeExpectancy     = 1
}

/// The age type, either Age or LifeExpectancy.
@NSManaged var ageType: AgeType
Run Code Online (Sandbox Code Playgroud)

在Core Data模型中,ageType设置为Integer 32类型.

  • 这个解决方案适用于Xcode 8/Swift 3/iOS 10,我只需要使用枚举`public`. (4认同)
  • @MobileBloke属性是否声明为可选? (2认同)

rin*_*aro 48

您可以Int16使用.rawValue属性提取原始值ObjStatus.

// compare
obj.state == ObjStatus.State1.rawValue

// store
obj.state = ObjStatus.State1.rawValue
Run Code Online (Sandbox Code Playgroud)

但是您可能希望stateEnum为它实现访问器:

class StateFullManagedObject: NSManagedObject {
    @NSManaged var state: Int16
    var stateEnum:ObjStatus {                    //  ? If self.state is invalid.
        get { return ObjStatus(rawValue: self.state) ?? .State1 }
        set { self.state = newValue.rawValue }
    }
}

// compare
obj.stateEnum == .State1

// store
obj.stateEnum = .State1

// switch
switch obj.stateEnum {
case .State1:
    //...
case .State2:
    //...
case .State3:
    //...
}
Run Code Online (Sandbox Code Playgroud)

  • 是的,这几乎就是我的工作.我将核心数据属性后缀为"Raw",然后使用具有正确名称的计算属性来处理从枚举到raw int的转换. (5认同)
  • 你应该**绝对**检查实际_clean_解决方案的另一个答案. (3认同)

rba*_*win 16

Xcode 12.5 斯威夫特 5

我将多个值存储Enums在数据库CoreDataCloudKit

要使其正常工作,需要执行相当多的精确步骤。我在这里列出了我所学到的行之有效的方法。

第 1 步:定义您的枚举:

标记它@objcpublic并且Int16

@objc
public enum SomeState: Int16 {
    case stateA
    case stateB
    case stateC
}
Run Code Online (Sandbox Code Playgroud)

第 2 步:在 xcdatamodeld 中创建一个用于存储 Enum 值的属性

类型应该是Integer 16

在此输入图像描述

步骤 3:在数据模型检查器中取消选中可选,然后设置默认值 0

这相当于 的第一个索引Enum

在此输入图像描述

步骤 4:在父实体的数据模型检查器中,将 Class Codegen 更改为 Manual/None

在此输入图像描述

第5步:创建NSManaged子类

单击实体名称,然后从菜单栏中选择编辑器 > 创建 NSManagedObject子类。确保目标设置为您的主项目。这将在项目导航器中创建两个新文件。

MyObject+CoreDataClass.swift

MyObject+CoreDataProperties.swift

步骤 6:在 MyObject+CoreDataProperties.swift 文件中将属性类型从 Int16 更改为 Enum 类型

extension MyObject {

    @NSManaged public var state: SomeState

}
Run Code Online (Sandbox Code Playgroud)

用法:

设置/更新值:

myObject.state = .stateA
Run Code Online (Sandbox Code Playgroud)

NSPredicate 搜索枚举值:

NSPredicate(format: "state = %i", SomeState.stateA.rawValue)
Run Code Online (Sandbox Code Playgroud)