Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use enums in RealmSwift?

I want to do something like this:

enum WeekDay {
    case Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
}

class Person: Object {

    dynamic var birthday: WeekDay? = .Monday
    dynamic var id: String? = nil
    dynamic var birthdayRaw: String? = nil

    override static func primaryKey() -> String? {
        return "id"
    }
}

But, I'm getting an error:

Property cannot be marked dynamic because its type cannot be represented in Objective-C

How can I solve this ? Thanks for any help.

like image 899
Tikhonov Aleksandr Avatar asked May 05 '16 12:05

Tikhonov Aleksandr


3 Answers

Realm doesn't have a direct way do it. Github issue.

But you can consider this trick

enum WeekDay: String {
    case Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
}

class Person: Object {
    private var _day: WeekDay?
    var birthday: WeekDay? {
        get {
            if let resolTypeRaw = birthdayRaw  {
                _day = WeekDay(rawValue: resolTypeRaw)
                return _day
            }
            return .Sunday
        }
        set {
            birthdayRaw = newValue?.rawValue
            _day = newValue
        }
    }

    dynamic var id: String? = nil
    dynamic var birthdayRaw: String? = nil

    override static func primaryKey() -> String? {
        return "id"
    }
}
like image 190
Tikhonov Aleksandr Avatar answered Nov 15 '22 05:11

Tikhonov Aleksandr


As of Realm 3.x you can use Int-based enums (apparently, by side-effect).

As of Realm 4.1 you can use any RawRepresentable enum (Int, Float, String) by complying with the "RealmEnum" protocol. Details in the pull request

like image 22
Eli Burke Avatar answered Nov 15 '22 06:11

Eli Burke


i've create an extension, i hope it will help you

import RealmSwift

protocol RealmPersistableEnum: RawRepresentable, _OptionalPersistable { }

extension RealmPersistableEnum where RawValue: _OptionalPersistable {
    static func _rlmGetProperty(_ obj: ObjectBase, _ key: PropertyKey) -> Self {
        Self(rawValue: RawValue._rlmGetProperty(obj, key)) ?? Self()
    }

    static func _rlmGetPropertyOptional(_ obj: ObjectBase, _ key: PropertyKey) -> Self? {
        guard let value = RawValue._rlmGetPropertyOptional(obj, key) else { return nil }
        return Self(rawValue: value)
    }
    
    static func _rlmSetProperty(_ obj: ObjectBase, _ key: PropertyKey, _ value: Self) {
        RawValue._rlmSetProperty(obj, key, value.rawValue)
    }
}

Use example

enum SomeEnumInt: Int, RealmPersistableEnum {
    case none = 0
    case test = 1
    case debug = 2

    init() {
        self = .none
    }
}

enum SomeEnumString: String, RealmPersistableEnum {
    case none
    case test
    case debug

    init() {
        self = .none
    }
}

class Foo: Object {
    @Persisted var v1: String
    @Persisted var v2: SomeEnumInt
    @Persisted var v3: SomeEnumString
}
like image 28
Alex Avatar answered Nov 15 '22 07:11

Alex