Realm-cocoa: Allow for non default, non optional properties in Swift

Created on 12 Mar 2015  路  9Comments  路  Source: realm/realm-cocoa

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'

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 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.

All 9 comments

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.

Was this page helpful?
0 / 5 - 0 ratings