ObjectMapper: Realm models that have a primary key seem to crash when mapped to JSON

I’m trying to integrate my ObjectMapper codebase (which I love!) with Realm, and I’m having a really hard time getting it to work with even the most simple setup. I have a class that just has a string “id” that I’m telling Realm is the primary key. When I call Mapper().toJSONString() on it, I get a crash: “Terminating app due to uncaught exception ‘RLMException’, reason: ‘Primary key can’t be changed after an object is inserted.’” If I remove the primary key, the crash goes away and behaves as intended, but I don’t see the point of using a database like Realm if I can’t use primary keys.


class IronObject: Object, Mappable {
    dynamic var id: String? = ""

    override static func primaryKey() -> String? {
        return "id"
    }

    convenience init(id: String) {
        self.init()
        self.id = id
    }

    convenience required init?(_ map: Map) {
        self.init()
        mapping(map)
    }

    func mapping(map: Map) {
        id              <- map["id"]
    }
}

let i = IronObject(id: "12345")
let realm = try! Realm()
try! realm.write {
    realm.add(i)
    print(Mapper().toJSONString(i))
}

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Reactions: 1
  • Comments: 15 (4 by maintainers)

Most upvoted comments

@ivanruizscm I also need the primary key in the json and I did like this:

if map.mappingType == .ToJSON {
    var id = self.id
    id <- map["id"]
}
else {
    id <- map["id"]
}

‘id’ is the realm object primary key. It worked!

For those also wondering, I have come up with a slightly more elegant solution:

switch map.mappingType {
    case .fromJSON:
        id <- map["id"]
    case .toJSON:
        id >>> map["id"]
}

Here id is the primaryKey in Realm.

@vitovalov

For Swift 4, use:

if map.mappingType == .toJSON

I think you may need to put an if clause around the primary key so that it is only set once:

if id == nil {
    id <- map["id"]
}

The ObjectMapper operator <- has an inout flag on the left hand side variable. This is only necessary when mapping data from JSON. However since the <- operator is also used for writing JSON, Realm assumes that the values are being modified when toJSONString is called.