Search code examples
swiftmultithreadingrealm

How to update a realm object once a result has been obtained from another thread?


How to update a realm object t point #1.

The issue is that there is a dependency on the result is required from the requestAuthorization call, which spawns a separate thread.

Using DispatchQueue.main.async did not help.

@IBAction func notificationToggle(_ sender: UISwitch) {

        if (sender.isOn){
            //Notifications being turned on


            UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) {
                (granted, error) in

                print("Permission granted: \(granted)")

                if granted{
                    myRealmObject.generateNotificationItems() //#1. Throws error due to not being in the main thread
                }
                else{
                    self.showNotificationsPrompt()
                }
            }
        }
        else{
            myRealmObject.deleteNotificationItems() //#2. This is fine, being in the main thread.
        }
    }

Solution

  • You can pass a Realm object across threads using a ThreadSafeReference as described here: https://realm.io/docs/swift/latest/#passing-instances-across-threads

    @IBAction func notificationToggle(_ sender: UISwitch) {
    
        if (sender.isOn){
            //Notifications being turned on
    
            let objectRef = ThreadSafeReference(to: myRealmObject)
    
            UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) {
                (granted, error) in
                autoreleasepool {
                    print("Permission granted: \(granted)")
    
                    if granted{
                        let realm = try! Realm()
                        guard let obj = realm.resolve(objectRef) else { return }
    
                        obj.generateNotificationItems()
                    }
                    else{
                        self.showNotificationsPrompt()
                    }
                }
            }
        }
        else{
            myRealmObject.deleteNotificationItems() //#2. This is fine, being in the main thread.
        }
    }