1

I have a bunch of methods saving camera names related to a video recording asynchronously in Realm database.

My model:

/**
 Realm object for saving the camera names used
 to record clip videos
*/
public class RMCamera: Object {

    dynamic var id = ""
    dynamic var name = ""

    override public class func primaryKey() -> String {
       return "id"
    }

}

The method saving the camera's in Realm:

/**
 Saves camera names for offline usage after deleting
 all current entries first.

 - parameter cameraNames: An array of string with the camera names to save
 */
public func saveCameraNames(cameraNames: [String]) {

    logv(" Saving camera names...")

    concurrentQueueBg.async {

        let realm = try! Realm()

        self.deleteCamerasFromRealm(realm)

        cameraNames.forEach { camera in

            let offlineCamera = RMCamera(value: ["id": NSUUID().UUIDString, "name": camera])

            do {
                try realm.write {
                    realm.add(offlineCamera)
                }
            } catch {
                loge("Error adding offline camera")
            }
        }

    }.notify(.Main) {
        logv("✅ Camera names saved!")
    }
}

And the method that first purges all camera entries from Realm:

/**
 Deletes all camera names saved in the passed Realm

 - parameter realm: A Realm database instance to use
 */
func deleteCamerasFromRealm(realm: Realm) {

    let cameras = realm.objects(RMCamera)

    try! realm.write {
        realm.delete(cameras)
    }
}

The problem is that every once in a while I am getting errors like this one:

Can't set primary key property 'id' to existing value '572cb087b974c25b01fa40c1'.

Any ideas what might be actually going wrong? I really don't think I am getting collisions from UUID generation.

Thanos
  • 844
  • 2
  • 11
  • 27
  • `572cb087b974c25b01fa40c1` doesn't look like a value that `-[NSUIID UUIDString]` would return (missing dashes, lowercase hex rather than uppercase that `NSUUID` uses). Did you intentionally use a bogus value in the error message you shared here, or is there somewhere else in your code that you're setting the ID to a value that comes from some other source? – bdash Jul 08 '16 at 20:12
  • To be honest, that's the hash that Crashlytics is reporting. I was bewildered too when I saw that. – Thanos Jul 08 '16 at 20:14
  • Also, @bdash, this is the only place in the code base that attributes of RMCamera are being set! – Thanos Jul 08 '16 at 20:33
  • It's exceptionally unlikely that different calls to `NSUUID().UUIDString` would return the same value, so I'm at a loss as to how you'd hit this exception given the code you've provided. – bdash Jul 08 '16 at 20:58
  • There are 2 broader problems here. First, why is Crashlytics an entirely different 32bit hash from the usual 128bit that NSUUID is supposed to create. Second, why I am getting the crash and the exception since the commit transaction is wrapped in a do/catch block... – Thanos Jul 08 '16 at 21:00
  • The answer to your second question is that attempting to insert a duplicate primary key throws an Objective-C exception rather than returning a Swift error. See the answers on http://stackoverflow.com/questions/38073777/how-to-handle-error-with-realm-during-writing/38080801 for information about why this is the case. – bdash Jul 08 '16 at 22:52
  • @bdash got it. From the code above can you see a case where `deleteCameras` won't delete all camera objects from Realm? Apart from the weird hash reported, that's another odd case. Why the exception is thrown although all cameras should have been deleted in the first place... – Thanos Jul 09 '16 at 08:00
  • Since `deleteCameras` uses a different write transaction than `saveCameraNames`, there's nothing preventing another thread from adding cameras between the point where `deleteCameras` returns and the point that `saveCameraNames` tries to add the new cameras. – bdash Jul 09 '16 at 13:38
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/116879/discussion-between-bdash-and-thanos). – bdash Jul 09 '16 at 15:59

0 Answers0