使用枚举作为 Realm 模型的 属性

Using enum as property of Realm model

我的模型可以使用枚举作为 属性 吗?我目前有一个 class 这样的:

class Checkin: RLMObject {
  dynamic var id: Int = 0
  dynamic var kind: String = "checked_in"
  var kindEnum: Kind = .CheckedIn {
    willSet { self.kind = newValue.rawValue }
  }

  enum Kind: String {
    case CheckedIn = "checked_in"
    case EnRoute = "en_route"
    case DroppedOff = "dropped_off"
  }
  ....
}

它工作正常,但我希望能够让 kind 属性 成为枚举并让 Realm 在 属性 上自动调用 .rawValue将对象保存到商店时。这在 Realm 中是否可行,或者是否已经有针对它的功能请求?

对于这种情况,您应该覆盖 kindEnum 的 setter 和 getter:

enum Kind: String {
  case CheckedIn
  case EnRoute
  case DroppedOff
}

class Checkin: Object {
  @objc dynamic var id = 0
  var kind = Kind.CheckedIn.rawValue
  var kindEnum: Kind {
    get {
      return Kind(rawValue: kind)!
    }
    set {
      kind = newValue.rawValue
    }
  }
}

我进一步改进了这个模型。

enum Thing: String {
    case Thing1
    case Thing2
    case Thing3
}

然后在我的领域 class 对象:

class myClass : Object {
    private dynamic var privateThing = Thing.Thing1.rawValue
    var thing: Thing {
        get { return Thing(rawValue: privateThing)! }
        set { privateThing = newValue.rawValue }
    }
}

这让我们可以写

myClassInstance.thing = .Thing1

(将 "Thing1" 存储到 privateThing 中),但阻止键入

myClassInstance.privateThing = "Thing4"

这不是有效值,因此要保持数据完整性。

由于 Realm 支持 Objective-C 枚举并且它们可以用 Int 表示,你可以使用这个:

class Checkin: Object {
  dynamic var id: Int = 0
  dynamic var kind: Kind = .checkedIn

  @objc enum Kind: Int {
    case checkedIn
    case enRoute
    case droppedOff
  }
  ....
}

如果您需要解析 to/from String,您可以使用 Kind 的自定义初始化器和 toString 函数。

GitHub

中有关于此的讨论

这适用于 Swift 3.0 和领域 2.0.2

Diogo T 的解决方案在最近更新 RealmSwift 之前有效。最终我们现在必须遵守 RealmEnum 协议才能成为 Realm Object.

的托管 属性
@objc enum MyEnum: Int, RealmEnum {
    ...
}

或在下面的某个地方添加:

extension MyEnum: RealmEnum { }

RealmSwift documentation for it

示例 RealmEnumRealmOptional

@objc enum MyEnum: Int, RealmEnum {
    case first
    case second
}

final class MyEntry: Object {
    //It should be let
    let someVariable = RealmOptional<CRUD>()
}

//using
myEntry.someVariable.value = MyEnum.first

避免强制展开的替代解决方案 得到 { return 东西(rawValue:privateThing)! }

enum Kind: String, CaseIterable {
      case CheckedIn
      case EnRoute
      case DroppedOff
    }

    @objc dynamic var kindRaw = Kind.CheckedIn.rawValue
    var kind: Kind {
        get {
            for kind in Kind.allCases where kindRaw == kind.rawValue {
                return kind
            }
            return .CheckedIn //default
        }
        set {
            kindRaw = newValue.rawValue
        }
    }

Realm 10.0.0 引入了 PersistableEnum 协议,无需任何第三方扩展即可轻松保留枚举值。

enum TaskStatusEnum: String, PersistableEnum {
    case notStarted
    case inProgress
    case complete
}
// To use the enum:
class Task: Object {
    // Required enum property
    @Persisted var status = TaskStatusEnum.notStarted 
    // Optional enum property
    @Persisted var optionalTaskStatusEnumProperty: TaskStatusEnum? 
}

干净简单的解决方案

来自 Realm 版本 >= 10.10.0can do this:

// Define the enum
enum StatusEnum: String, PersistableEnum {
    case notStarted
    case inProgress
    case complete
}

// To use the enum:
class Task: Object {
    @Persisted var status = StatusEnum.notStarted 
}