Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift + Realm newbie: Problems with a simple Realm object and its initializers

I've been a long time Objective-C developer and heard about Realm some weeks ago. On the other hand I've always wanted to migrate little by little to Swift, so I created a small project involving Realm + Swift.

What does it mean? I'm a Swift + Realm newbie.

Anyway, I created a small demo/Proof of concept for a project I have in mind and I thought it had to be easier. But Xcode compiler says otherwise.

My problem is with one of my Objects' initializer(s).

My intentions were simple, but apparently Realm needs more initializers than I wanted.

The code of one of my Realm Objects is this:

import Foundation

import Realm
import RealmSwift

class Partida: Object
{
    dynamic var id_partida: String
    dynamic var inventario: Inventory?

    required init ()
    {
        inventario = Inventory()
        id_partida = "id_partida_test"
        super.init()
    }



    required init(value: AnyObject, schema: RLMSchema) {
        //fatalError("init(value:schema:) has not been implemented")
        super.init(value: value, schema: schema)
    }


    required init(realm: RLMRealm, schema: RLMObjectSchema) {
        //fatalError("init(realm:schema:) has not been implemented")
        super.init(realm: realm, schema: schema)
    }

    override class func primaryKey() -> String? {
        return "id_partida"
    }

}

My original code only had the "normal" init initializer. But Xcode forced me to create two additional initializers more (value and realm ones).

If I compile the code I've just pasted above, Xcode complains in the 2nd and 3rd required initializers, specifically in the super.init part. It says:

Property 'self.id_partida' not initialized at super.init call

I understand the meaning of it, but I don't know how to avoid the error because if I remove both super.init lines, the program crashes in runtime.

if I uncomment the fatalError lines, they also crashes in runtime.

In fact I don't want to use these 2 initializers. If I could, I wouldn't add them, but Xcode needs to, apparently. The only code I really want to add to my object init function is "the simple" init function, which was the only part of code considered mine.

I think I might have some concept misunderstandings in Realm + Swift + initializers.

I'm also having the feeling Xcode is forcing me to add code I don't need and/or I don't understand either.

Any help on understanding "required init" initializers in Realm will be more than welcome.

Official Realm + Swift documentation is beyond my knowledge as I don't understand many of its concepts even after re-reading them many times.

Google and StackOverflow haven't been really helpful this time...

Thanks.

like image 375
Isaac Avatar asked Apr 25 '16 10:04

Isaac


2 Answers

Initializers in Swift definitely behave a bit differently to Objective-C, so I can definitely see the angle you're coming from here.

In this case though, since you're just using the initializer to set some default values, it's wholly un-necessary since you should be able to assign the default values to the properties themselves:

class Partida: Object
{
    dynamic var id_partida = "id_partida_test"
    dynamic var inventario: Inventory? = Inventory()

    override class func primaryKey() -> String? {
        return "id_partida"
    }

}

Let me know if that still doesn't work! :)

like image 100
TiM Avatar answered Sep 29 '22 00:09

TiM


Because it already has init () in Object class, you are using subclass of Object, so you already have its init in Realm object, you should give your var init value, like dynamic var id_partida: String = "id_partida_test", and then if you call let test = Partida() it already has your 2 init value, other init should be marked with convenience

When you save the Object to persistent store, it should be always have value, you can use Realm's optional then need read the documentation

Here's my sample Realm class so that u got the idea:

import Foundation
import RealmSwift
import SwiftyJSON

class ProjectModel: Object {
    dynamic var id: Int = 0
    dynamic var name: String = ""

    //Dont need this, call init() already have value
    required init() {
       id = 0
       name = ""
       super.init()
    }

    convenience init(fromJson json: JSON!){
        self.init()

        if json == nil {
            return
        }

        id = json["id"].intValue
        name = json["name"].stringValue
    }

    override class func primaryKey() -> String? {
        return "id"
    }
}
like image 38
Tj3n Avatar answered Sep 28 '22 23:09

Tj3n