Search code examples
swiftrealmswift4realm-mobile-platform

Realm Swift subclassing


I have two models that I am trying to subclass in swift using RealmSwift

Model 1: Users

@objcMembers class User: Object, Codable {

    dynamic var id: Int = 0
    dynamic var username: String = ""
    dynamic var email: String = ""
    dynamic var counts: Counts = Counts(follows: 0, followed_by: 0)

    convenience init(id: Int, username: String, email: String, counts: Counts) {
        self.init()
        self.id = id
        self.username = username
        self.email = email
        self.counts = counts
    }    
}

class Counts: Codable {
    let follows: Int
    let followed_by: Int

    init(follows: Int, followed_by: Int) {
        self.follows = follows
        self.followed_by = followed_by
    }
}

Here I created a model which inherits codable because I am using Swift 4 new decoding method. This model works fine. I can go add a user and read it fine. So doing this works fine:

let newUser = User(id: 1, username: "user1", email: "[email protected]", counts: Counts(follows: 100, followed_by: 500000000))

RealmService.shared.write(newUser)

Now I am trying to create a model called Friend which has a field that inherits from User

Model 2: Friend

@objcMembers class Friend: Object {

    dynamic var user: User = User(id: 0, username: "", email: "", counts: Counts(follows: 0, followed_by: 0))
    dynamic var dateAdded: Date = Date(timeIntervalSinceNow: 0)

    convenience init(user: User, dateAdded: Date = Date(timeIntervalSinceNow: 0)) {
        self.init()
        self.user = user
        self.dateAdded = dateAdded
    }
}

When I do this and load up my app I get a SIGBART and it highlights my initialization of realm : let realm = RealmService.shared.realm

When I remove my Friend Model the app works fine.

How do you properly subclass in Realm?


Solution

  • You cannot declare properties as normal Swift properties whose types are other Realm subclasses. What you are looking for is a many-to-one relationship.

    Many-to-one relationships have to be declared optionals and you can't provide a default value

    @objcMembers class Friend: Object {
    
        dynamic var user: User?
        dynamic var dateAdded: Date = Date()
    
        convenience init(user: User, dateAdded: Date = Date()) {
            self.init()
            self.user = user
            self.dateAdded = dateAdded
        }
    }
    

    Unrelated, but when you want to create a Date object representing the current time, just call the default, empty initializer of Date, it will do that for you and it's much shorter than Date(timeIntervalSinceNow: 0).