2

Say I have a class and its Realm representation that looks like this:

class Dog {
    var identifier: String
    var age: Int
    ...

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

Now here is what my new Identifier class looks like:

class Identifier {
    var functionalId: String
    var version: String
    ...
}

I need to replace my Dog's identifier String property to be an Identifier like this:

class Dog {
    var identifier: Identifier
    var age: Int
    ...

    override static func primaryKey() -> String? {
        return "identifier" // I need to change this
    }
}

but I'm having a hard time replacing the content of the primaryKey() method:

How do I tell Realm to look for an object's sub property for the primaryKey() ?

I tried something like:

override static func primaryKey() -> String? {
    return "identifier.functionalId"
}

But it seems that I was too naive, it won't work

** EDIT ** Following comments, here is the output of the crash I'm getting:

Terminating app due to uncaught exception 'RLMException', reason: 'Primary key property 'identifier.functionalId' does not exist on object Dog

Sorry for bad English though, I couldn't find the words fir this simple problem, especially the title!

H4Hugo
  • 2,570
  • 3
  • 16
  • 32
  • "I'm having a hard time replacing the content" > are you getting any errors reported by Realm? – Kane Cheshire Sep 26 '18 at 08:07
  • Thanks for asking, I edited the question to include the crash's log – H4Hugo Sep 26 '18 at 08:16
  • What error do you get if you just set it to`"identifier"` rather than `"identifier.functionalId`? – Kane Cheshire Sep 26 '18 at 08:21
  • *** Terminating app due to uncaught exception 'RLMException', reason: 'Property 'identifier' cannot be made the primary key of 'Dog' because it is not a 'string' or 'int' property.' – H4Hugo Sep 26 '18 at 08:33
  • I think that answers the question then! The primary key can only be a `String` or `Int`, and can only be a property on `Dog`. I'll add an answer below. – Kane Cheshire Sep 26 '18 at 08:38
  • Have a look at [Composite primary key Realm Swift](https://stackoverflow.com/questions/31265666/composite-primary-key-realm-swift), the same workaround should work for your case as well. – Dávid Pásztor Sep 26 '18 at 10:52

2 Answers2

1

I've never tried this in Realm, but it might be possible using a dynamic variable for your primary key and a function that pulls the value from the sub-object:

var _identifier: Identifier

dynamic lazy var identifier: String = self.identifierValue()

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

func identifierValue() -> String {
    return _identifier.functionalId
}
davidethell
  • 11,708
  • 6
  • 43
  • 63
0

How do I tell Realm to look for an object's sub property for the primaryKey()

You can't.

Looking at the errors you've mentioned:

If you try setting the primary key to:

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

Then you get an error from Realm saying: Property 'identifier' cannot be made the primary key of 'Dog' because it is not a 'string' or 'int' property.

If you try setting the primary key to:

override static func primaryKey() -> String? {
    return "identifier.functionalId"
}

Then you get an error from Realm saying: Primary key property 'identifier.functionalId' does not exist on object Dog

This leads to the conclusion that the primary key must be of type String or Int, and it must be a property of Dog, not another class.

Kane Cheshire
  • 1,654
  • 17
  • 20