Crash when app starts for the first time (Primary key property ... does not exist on object

I am upgrading an iOS app from iOS9 to iOS13 (yeah, I should have kept up with the changes, but well . . .). It is based on Swift and uses RealmSwift for the database. After clearing out 2400 errors and updating the pods I got to the point of launching the app in the iOS 13 simulator (iPhone 11 Pro Max) in Xcode 11 (version 11.3.1) only to have Realm crash with an exception of 'Primary key property {some id} does not exist on object {some object}.

I figured I messed something up and built a simple single view test application to see whether this was a cocoapods update issue or I had missed something. At anyr ate, in the end, I found my test app failed with the same error. I’m sure (hoping) it is something simple I have overlooked.

I did find a few stack overflow issues for when Xcode 11 was in beta (back in July of 2019), and those pointed to test versions of RealmSwift in the 3.x range. But we are way past that now and I figure this has been solved. So any help would be much appreciated:

My podfile looks like this:

platform :ios, '13.0'

target 'RealmTest' do
  use_frameworks!
  pod 'RealmSwift'
end

I checked my Podfile.lock and it ends up looking like this (which appears to be the latest):

PODS:
  - Realm (4.3.2):
    - Realm/Headers (= 4.3.2)
  - Realm/Headers (4.3.2)
  - RealmSwift (4.3.2):
    - Realm (= 4.3.2)

DEPENDENCIES:
  - RealmSwift

SPEC REPOS:
  trunk:
    - Realm
    - RealmSwift

Now for the app code.

My model looks like this:

import Foundation
import RealmSwift

class DataItem: Object {
    dynamic var dataId = UUID().uuidString
    dynamic var value = ""
    
    override static func primaryKey() -> String? {
        return "dataId"
    }
}

And my view controller that uses this model looks like this:

import RealmSwift

class ViewController: UIViewController {

    @IBOutlet weak var table:UITableView!
    
    var realm:Realm?
    var dataItems: Results<DataItem>?
    var token: NotificationToken? = nil
    
    override func viewDidLoad() {
        super.viewDidLoad()
        realm = try! Realm()
        if let realm = realm {
            token = realm.observe { notification, realm in
                self.updateUI() 
            }
        }
    }

    private func updateUI() {
        if let realm = realm {
            dataItems = realm.objects(DataItem.self)
            table.reloadData()
        }
    }
    
    @IBAction func addItem() {
        // get a string representation of the date/time
        let now = Date()
        let formatter = DateFormatter()
        formatter.timeStyle = .medium
        
        // create a DataItem
        var dataItem = DataItem()
        dataItem.value = formatter.string(from: now)
        
        // store in the Realm
        addToRealm(dataItem)
    }
    private func addToRealm(_ item: DataItem) {
        guard let _realm = realm else {
            print("No realm is configured")
            return
        }
        try! _realm.write() {
            _realm.add(item)
        }
    }

}

extension ViewController:UITableViewDelegate {
    
}

extension ViewController:UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if let collection = dataItems {
            return collection.count
        }
        return 0
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "DataItemCell", for: indexPath)
        guard let dataCell = cell as? DataItemCell else {
            return cell
        }
        if let collection = dataItems {
            let item = collection[indexPath.row]
            dataCell.configure(item)
        }
        return dataCell
    }  
}

That’s the entirety of the app other than the AppDelegate, the storyboard, and the cell definition.

As the app starts up I get this exception

2020-02-23 17:28:59.987449-0500 RealmTest[1923:130948] *** Terminating app due to uncaught exception ‘RLMException’, reason: 'Primary key property ‘dataId’ does not exist on object ‘DataItem’'

This happens on initial app startup. I have done the usual (XCode hates me, clean build folder, delete derived data folder, restart XCode, restart Mac) but nothing has helped.

I’m really at a loss as to how to solve this, so any help would be greatly appreciated

You forgot the @objc dynamic in your Realm class

Should be

class DataItem: Object {
    @objc dynamic var dataId = UUID().uuidString
    @objc dynamic var value = ""
    
    override static func primaryKey() -> String? {
        return "dataId"
    }
}

or you can make the whole class managed with

@objcMembers class DataItem: Object {
    dynamic var dataId = UUID().uuidString
    dynamic var value = ""
    
    override static func primaryKey() -> String? {
        return "dataId"
    }
}

Thanks so much!! That solved it. I made the whole class managed. For future viewers the class modifier is “@objcMembers”, notice the plural part. So the model that worked for me was:


import Foundation
import RealmSwift

@objcMembers class DataItem: Object {
    dynamic var dataId = UUID().uuidString
    dynamic var value = ""
    
    override static func primaryKey() -> String? {
        return "dataId"
    }
    
}

Apparently when moving from Swift (I’m not sure which version, it was at iOS8 though) I didn’t have to have the @objc annotiations, so that is how I missed it when moving to Swift 5.1 (at least that’s the story I am going with). Again, thanks for your help

1 Like