使用枚举作为 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
函数。
中有关于此的讨论
这适用于 Swift 3.0
和领域 2.0.2
Diogo T 的解决方案在最近更新 RealmSwift 之前有效。最终我们现在必须遵守 RealmEnum
协议才能成为 Realm Object
.
的托管 属性
@objc enum MyEnum: Int, RealmEnum {
...
}
或在下面的某个地方添加:
extension MyEnum: RealmEnum { }
示例 RealmEnum
和 RealmOptional
@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.0
你 can 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
}
我的模型可以使用枚举作为 属性 吗?我目前有一个 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
函数。
这适用于 Swift 3.0
和领域 2.0.2
Diogo T 的解决方案在最近更新 RealmSwift 之前有效。最终我们现在必须遵守 RealmEnum
协议才能成为 Realm Object
.
@objc enum MyEnum: Int, RealmEnum {
...
}
或在下面的某个地方添加:
extension MyEnum: RealmEnum { }
示例 RealmEnum
和 RealmOptional
@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.0
你 can 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
}