In order to be able to use generics for object initialization using the copy initializer init(value:) this needs to be marked as required for Swift to compile. Consider the following example:
func changePrimaryKey<Element: Object, KeyType>(ofType type: Element.Type, from oldKey: KeyType, to newKey: KeyType) -> Element? {
if let element = realm.object(ofType: type, forPrimaryKey: oldKey), let primaryKey = type.primaryKey() {
let copy = Element(value: element) // compiler error
realm.delete(element)
copy[primaryKey] = newKey
realm.add(copy)
return copy
}
return nil
}
The code example above should compile. Marking this as required should not have limiting consequences as I don't see developers actually removing this initializer in their subclasses (which can be done with non-required initializers). On the negative side, developers that implement their own initializers will need to implement both init() and init(value:).
The Swift compiler throws the following error: Constructing an object of class type 'Element' with a metatype value must use a 'required' initializer.
I know this has already been discussed in https://github.com/realm/realm-cocoa/pull/2514, but the situation hasn't really changed and I'm still unable to elegantly work around this limitation. Also, it doesn't look like Swift will change this restriction anytime soon. Providing an instance method to do the same (e.g. copyFromRealm()) would also solve the underlying problem. Thanks for your consideration!
Realm framework version: 3.3.0
Realm Object Server version: none
Xcode version: 9.3
iOS/OSX version: 11.3
Dependency manager + version: CocoaPods 1.4.0
Same for me.
@TR4Android, as a workaround you could use this method:
// WARNING: This is an internal initializer not intended for public use.
let copy = Element(value: element, schema: .partialPrivateShared())
@jpsim I've found that internal initializers marked with FIXME for about 3 years
public override required init(value: Any, schema: RLMSchema)
But this methods is required for generic functions like JSON mapping functions.
So, I'm wondering how long this useful initializers will be available in public RealmSwift interface? May I use it for production code?
Same for me. This is what I have been using for a while on my realm model objects.
func unmanaged() -> Self {
if self.realm == nil {
return self
} else {
return type(of: self).init(value: self, schema: .partialPrivateShared())
}
}
This is not available in the latest versions of realm
No longer applicable as of 4.0.
Most helpful comment
Same for me. This is what I have been using for a while on my realm model objects.