I would like to have a model that doesn't have any default values nor optionals. But I cannot figure out how to do it and I guess it's simply not possible.
What I want to do is basically:
class Person: RLMObject {
dynamic var name: String
dynamic var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
super.init()
}
}
This crashes at runtime due to: Person.swift: 12: 7: fatal error: use of unimplemented initializer 'init()' for class 'RealmTryout.Person'
Hi Petaren! Currently with Realm you do need to have default values for each property you create. Hope this helps
To add a bit more context here, Realm uses Swift's runtime reflection to determine the layout of your model classes. Because Swift's reflect(_:) requires to pass in an instance, Realm will require that calling init() on your model class actually returns an instance that can be reflected.
So you can still use custom initializers (e.g. init(name: String, age: Int)) as long as you also implement init(). However, you can choose to never call init() in your own code.
If you'd like this situation to be improved, please file a radar at http://bugreport.apple.com so that Apple can make Swift reflection flexible enough to allow introspecting classes without having to create an instance.
Thank you for your comments!
@jpsim can you please show here some working example with custom initializer? I'm trying to build it and init() seem not enough.
12: 7: fatal error: use of unimplemented initializer 'init(realm:schema:)'
Model
class MyModel: Object {
dynamic var stringProperty = ""
convenience init(stringProperty: String) {
self.init()
self.stringProperty = stringProperty
}
}
Usage
let realm = Realm()
realm.write {
realm.add(MyModel(stringProperty: "abcd"))
}
println(realm.objects(MyModel))
// Prints:
//
//Results<MyModel> (
// [0] MyModel {
// stringProperty = abcd;
// }
//)
@jpsim fatal error: use of unimplemented initializer 'init(realm:schema:)' for class 'MyModel'
the full code must override init() and init(realm: RLMRealm, schema: RLMObjectSchema) to work.
import RealmSwift
import Realm
class MyModel: Object {
dynamic var stringProperty = ""
override init() {
super.init()
}
override init(realm: RLMRealm, schema: RLMObjectSchema) {
super.init(realm: realm, schema: schema)
}
convenience init(stringProperty: String) {
self.init()
self.stringProperty = stringProperty
}
}
It's not currently possible to override Object.init(). This is something we'd like to fix. We're tracking this issue as #1849.
If you change your model definition to this, your convenience initializer should work:
class MyModel: Object {
dynamic var stringProperty = ""
convenience init(stringProperty: String) {
self.init()
self.stringProperty = stringProperty
}
}
You shouldn't have to import Realm when using Realm Swift. If you find yourself needing something from the Realm module that's missing from RealmSwift, please file an issue here. We aim to have feature parity across both frameworks.
@jpsim my fault.
@krzyzanowskim don't worry about it, we understand the expectation is for this to _just work_, and we'll continue to do our best to reduce the number of "rough edges" like these.
Most helpful comment
To add a bit more context here, Realm uses Swift's runtime reflection to determine the layout of your model classes. Because Swift's
reflect(_:)requires to pass in an instance, Realm will require that callinginit()on your model class actually returns an instance that can be reflected.So you can still use custom initializers (e.g.
init(name: String, age: Int)) as long as you also implementinit(). However, you can choose to never callinit()in your own code.If you'd like this situation to be improved, please file a radar at http://bugreport.apple.com so that Apple can make Swift reflection flexible enough to allow introspecting classes without having to create an instance.