Emil Osvald
Emil Osvald

Reputation: 1907

Realm addNotificationBlock returning error

I have been trying to setup Realm database and everything has worked fine so far. Now that I am trying to create a notification token in order to track changes in my Realm, addNotificationBlock method returns the following error:

Error Domain=io.realm Code=1 "std::exception" UserInfo={NSLocalizedDescription=std::exception, Error Code=1}

I have read the API reference and I do understand that:

This can only currently happen if opening the Realm on a background thread to calcuate the change set fails.

Unfortunately this does not help me to figure out the reason why such a failure happens. In my app I have a Realm database of 100 objects and I am trying to present every object where variable location = 2. I would like to listen to notifications about the changes in the Results object containing all these objects.

Code in my ViewController:

import UIKit
import RealmSwift

class PatientCell: UITableViewCell {

    @IBOutlet weak var hetu: UITextView!
    @IBOutlet weak var name: UITextView!
    @IBOutlet weak var photo: UITextView!

}

class PäivystyslistaVC: UIViewController, UIScrollViewDelegate, UITableViewDelegate, UITableViewDataSource, UIPopoverControllerDelegate {

    @IBOutlet weak var tableView: UITableView!
    @IBOutlet var patientPopupView: UIView!

    var patients: Results<Patient2>!
    var realm = try! Realm()
    var timer: Timer!
    var notificationToken: NotificationToken? = nil

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self
        tableView.delegate = self
        let realm = try! Realm()
        patients = realm.objects(Patient2.self).filter("location = 2")

        print("Patients on the ER: \(patients)")

        notificationToken = patients.addNotificationBlock { (changes: RealmCollectionChange) in
            switch changes {
            case .initial:
                print("From initial")
                break
            case .update:
                print("From update")
                break
            case .error(let err):
                print("Error occured \(err)")
                break
            }
        }

        timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(self.addPatient), userInfo: nil, repeats: true)
    }

    func addPatient() {
        print("")
        print("Timer launched")
        print("Patients on the ER: \(patients.count)")
        sendPatientToER()
        print("")
        tableView.reloadData()
    }



    // MARK: TableView:n hallinta
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return patients.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "patient", for: indexPath) as! PatientCell

        let patient = patients[indexPath.row]
        cell.hetu?.text = patient.hetu
        cell.name?.text = patient.fullName
        cell.photo?.text = patient.photo

        return cell

    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let potilastiedotVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PotilastiedotVC")
        self.present(potilastiedotVC, animated: true, completion: nil)

        tableView.deselectRow(at: indexPath, animated: true)
    }

    func tableView(_ tableView: UITableView, editActionsForRowAt: IndexPath) -> [UITableViewRowAction]? {
        let kotiuta = UITableViewRowAction(style: .normal, title: "Kotiuta") { action, index in
            try! self.realm.write {
                self.realm.create(Patient2.self, value: ["id": index.row, "location": 1], update: true)
            }
            self.tableView.deleteRows(at: [index], with: .left)

        }
        kotiuta.backgroundColor = UIColor.vihreä

        let osastolle = UITableViewRowAction(style: .normal, title: "Osastolle") { action, index in
            try! self.realm.write {
                self.realm.create(Patient2.self, value: ["id": index.row, "location": 3], update: true)
            }
            self.tableView.deleteRows(at: [index], with: .top)
        }
        osastolle.backgroundColor = UIColor.oranssi

        let lähetä = UITableViewRowAction(style: .normal, title: "Lähetä") { action, index in
            try! self.realm.write {
                self.realm.create(Patient2.self, value: ["id": index.row, "location": 3], update: true)
            }
            self.tableView.deleteRows(at: [index], with: .top)
        }
        lähetä.backgroundColor = UIColor.vaaleansininen

        return [kotiuta, lähetä, osastolle]
    }

And a helper method in another file:

import UIKit
import RealmSwift

    func sendPatientToER() {
        let realm = try! Realm()
        let count = realm.objects(Patient2.self).filter("location == 1").count
        print("Count of patients waiting at home: \(count)")
        let randomId = Int(arc4random_uniform(UInt32(count)))
        print("Random id generated: \(randomId)")
        realm.beginWrite()
        realm.create(Patient2.self, value: ["id": randomId, "location": 2], update: true)
        try! realm.commitWrite()
    }

Thank you in advance.

Upvotes: 0

Views: 292

Answers (1)

Thomas Goyne
Thomas Goyne

Reputation: 8138

An untranslated std::exception is never supposed to make it out of Realm, so that part is a bug.

If you can consistently reproduce the issue, you can set an exception breakpoint in Xcode to break at the point where the error is actually occurring and hopefully find out what's wrong that way.

Upvotes: 1

Related Questions