-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support Swift enums #921
Comments
Your work-around is the best way to accomplish this for the time being. There are several implications we need to consider before adding official support for Swift enum's, especially concerning migrations. In any case, thanks for the feature request! |
This would be really nice to have, especially when dealing with JSON data. In the meanwhile the snippet by @aschuch (thank you!) can be a little shorter using var state: State {
return State(rawValue: stateRaw) ?? .Closed
} |
Is this still the case now that we have RealmSwift? |
@danyalaytekin unfortunately, this is still the case, as Realm Swift still relies on properties being |
@segiddins np, thanks for the quick confirmation! 👍 |
Would love to see this implemented! Thanks guys! |
@frazer-rbsn this is still impossible, even as of Swift 2.0, as the runtime doesn't give us the information we need to be able to determine what we need to store under the hood. |
@segiddins |
For anyone who comes across this in the future -- KVC is a little bit trickier with using the raws if you don't want external users to have to worry about remembering which fields are backed by raws. So I've found a good way is to override the |
Any progress/updates on this guys? This is really a core use case for domain modeling, would be super useful to have this supported first-hand (or at least a section about the current best-practice workaround in the docs). Pretty please. |
@segiddins In terms of runtime not giving you enough info, what do you mean by this? Could you not require provide a simple protocol that users would adopt on their enums to give you whatever it is that's needed (ie: CustomStringConvertible for example if you need to map the enum to a string to persist). Or your own RealmEnumValueConvertible in case the user already implemented CustomStringConvertible and wants to differ the persisted value from it (rare, but could be valid in certain cases). PS: I find the deltas between the model objects and what's needed to persist them in Realm is really blowing up our domain - I think it would be a great goal for the team to try to prioritize minimizing these differences for the overall adoption/practicality of the framework. Enum persistence would be a great win on this front. |
Is there any changes as for Swift 3.0? |
Yes, lots. But none regarding Swift enums and Realm. |
@jpsim I think what @piv199 meant was whether Swift 3.0 added any of the runtime info that @segiddins mentioned eg: "...as of Swift 2.0, as the runtime doesn't give us the information we need to be able to determine what we need to store under the hood". Also, what do you guys think of my proposed solution to provide a protocol that enums can adopt in order to provide you with the serialized info you need? |
Yes, I understood that, but should have been clearer in my response. There are no changes in Swift 3 that would allow us to do this.
This would have to be done more comprehensively, allowing the decomposition of all types into Realm primitives in order to keep Realm files cross-platform, but yes this is something that should be done. |
It's possible to declare scalar-type-backed enums as @objc. Properties with declared @objc enum types can de marked dynamic, so wouldn't this enable realm to access the values? I've used this approach with Core Data in the past: import CoreData
class Thread: NSManagedObject {
@NSManaged var state: State // @NSManaged == dynamic
@objc enum State: Int64 {
case ready
case running
case waiting
}
} EDIT: Actually, this already works, as far as I can tell. import RealmSwift
class Thread: Object {
dynamic var state: State = .ready
@objc enum State: Int {
case ready
case running
case waiting
}
} It would be awesome to get RealmOptional support for these enums too, since that still seems impossible. |
Would native enums be easier to support with the changes introduced in Swift 4.2, or is there anything else required? |
It was mention in #2375 that work is being done on supporting types that implement Recently I've started using the Tagged library. So I do something along the lines of: final class Todo: Object {
enum TodoIdTag {}
typealias Identifier = Tagged<TodoIdTag, String>
@objc dynamic var rawId: Identifier.RawValue = UUID().uuidString
var id: Identifier {
get {
return Identifier(rawValue: self.rawId)
}
set {
self.rawId = newValue.rawValue
}
}
} However this gets really confusing when finding a single object using It would be great if Maybe something like: extension RawRepresentable: CustomObjectiveCBridgeable where RawValue: CustomObjectiveCBridgeable {
static func bridging(objCValue: Any) -> Int64 {
return objCValue as! RawValue
}
var objCValue: Any {
return self.rawValue
}
} |
The big limiting factor is that the property getter/setters which actually read from and write to the Realm file are implemented via the objective-c runtime, which means that they have to be types which obj-c supports. RealmOptional and List circumvent this by doing fairly complicated things that unfortunately involve a hardcoded list of the supported types on the obj-c side, so it wouldn't be totally straightforward to generalize it to a type which lets you pick a storage type, a mapped type, and a conversion function. SE-0258 probably will make it possible to at least make the wrapper property approach a lot simpler and work better, but as always the fact that it doesn't really interop with obj-c may limit how good the end result can be. |
@tgoyne Two questions on this front:
Thanks for your honest thoughts on all this. |
Supporting obj-c isn't limiting what we can do in Swift. We're perfectly willing to ship Swift-only features, and splitting the obj-c and swift SDKs into entirely separate SDKs is on the table if there's ever a solid reason to do so (although it's worth noting that if we did, the obj-c SDK would have a large enough user base to continue maintaining it). We continue to do things via the obj-c runtime because Swift lacks the language features needed to make things work without a compile-time code generation step, and without compiler support to make that painless (as Java and .NET have) we don't consider that a viable path. I put together a prototype of property wrapper based model definitions a year ago. It doesn't dramatically change what we can support unfortunately; it'd let us support things like I haven't had a chance yet to look into single-property publishers to see if there's anything useful we could do there. |
The |
Swift adds great new features to enums.
However, it is not possible to directly persist enums to a Realm, because of the libraries use of the
dynamic
keyword (Obj-C only).At the moment I am solving such issues like the following, but this should really be handled by the RLMObject behind the scenes.
Open for other suggestions ✨
The text was updated successfully, but these errors were encountered: