JoonSoo Park
JoonSoo Park

Reputation: 43

Swift Realm Object and Mappable

I'm using "Realm" and "ObjectMapper" in swift

"Realm" does not support inheritance, so I have to make model like this:

class Model1 : Object, Mappable
class Model2 : Object, Mappable

And I wanted to make a function that find local data with model name in string and primary key.

func fetchLocal(name : String, key : String)->Object{
    switch(name){
        case "Model1":
            ~~~~
            return Model1
        case "Model2":
            ~~~~
            return Model2
    }
}

And when I using this function, cast object to Mappable

if let mappable = fetchLocal(name : "Model1", key: "~~~~") as? Mappable{
    let json = mappable.toJSON()
}

Then run time error comes out without message like :

Thread 1: EXC_BAD_ACCESS (code = 1, address = 0x0)

I tracked this error but app just crash in Mappable.swift at:

public func toJSON() -> [String: Any] {
    return Mapper().toJSON(self)         <------here
}

I think the reason is that function "fetchLocal" just return "Object" not "Mappable", but returning class is obviously implements "Mappable", so it passes the "if let as" clause, but error comes out when calling "toJSON()".

As "Realm Object" cannot be implemented, I cannot make a class like "ObjectMappable : Object, Mappable" and let the "fetchLocal" function to return "ObjectMappable"

So, I think only option is making "fetchLocal" function to return a class that implements "Object and Mappable", but I don't know how.

Please, help me.

Upvotes: 3

Views: 1488

Answers (1)

Carlos Chaguendo
Carlos Chaguendo

Reputation: 3085

public class Model: Object, Mappable {

    public required init(map: Map) {
        super.init()
    }

    required public init() {
        super.init()
    }

    required public init(realm: RLMRealm, schema: RLMObjectSchema) {
        super.init(realm: realm, schema: schema)
    }

    required public init(value: Any, schema: RLMSchema) {
        super.init(value: value, schema: schema)
    }

    public override init(value: Any) {
        super.init(value: value)
    }

    public func mapping(map: Map) {

    }

}

realm query

func fetchLocal<AnyModel: Model>( type: AnyModel.Type, key: String ) -> AnyModel {
    yourRealm.object(ofType: type, forPrimaryKey: key)
}

Any model

class Model1 : Model {

}

select

let m:Model1? = fetchLocal(type: Model1.self, key: "1")

Upvotes: 1

Related Questions