Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RLMException: 'Primary key property 'serial' does not exist on object 'Book' Migrating to Swift 4

Tags:

ios

swift

realm

I'm running into this issue with Realm on iOS using Swift 4 compilation, where on startup the app crashes with the following message

RLMException', reason: 'Primary key property 'serial' does not exist on object 'Book''

I saw similar error messages, but not the same one. This is what my object looks like

import Foundation
import RealmSwift

class Book: Object {
    dynamic var serial: String = ""
    dynamic var title: String = ""
    dynamic var pages: Int = 0
    dynamic var genre: String = ""

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

When I checked the default.realm file through the Realm Browser app, I noticed that the entries only have a # (0,1,2) and no data in it. If I comment out the primary key, it runs, but nothing is stored in Realm for this object. Can't figure out why it's crashing!

like image 980
Hellojeffy Avatar asked Feb 15 '18 15:02

Hellojeffy


3 Answers

Although it doesn't necessarily about migration, there's an issue with iOS 13 and Xcode 11 which may cause this problem. All String properties of Realm classes with a default String value set are disregarded somehow. You can fix this by updating to the latest version (currently 3.20.0) and than on Xcode: Product -> Clean Build Folder.

If you're using cocoa-pods, do this:

Open your project's Podfile, and replace RealmSwift line with:

pod 'RealmSwift', '~> 3.20.0'

Then, open terminal on the project's folder and:

pod repo update
pod install

Hope that helps.

like image 171
Gal Shahar Avatar answered Nov 17 '22 04:11

Gal Shahar


In Realm, the properties of your model have to have the @objc dynamic var attribute, that is what I was missing.

From Realm website:

Realm model properties must have the @objc dynamic var attribute to become accessors for the underlying database data. Note that if the class is declared as @objcMembers (Swift 4 or later), the individual properties can just be declared as dynamic var.

like image 30
Hellojeffy Avatar answered Nov 17 '22 04:11

Hellojeffy


import Foundation
import RealmSwift

class Book: Object {
   @objc dynamic var id : Int = 0
   @objc dynamic var serial: String = ""
   @objc dynamic var title: String = ""
   @objc dynamic var pages: Int = 0
   @objc dynamic var genre: String = ""

    override static func primaryKey() -> String? {
        return "id"
    }
}
like image 9
Khawar Islam Avatar answered Nov 17 '22 04:11

Khawar Islam