Updating Realm object with Nil not working

Rioco

How can I update Realm object with nil? The image recovers after users delete the Image, and save on the app with Swift5. The object value wasn't changed when I tried to set 'nil' to the Realm object directly for debugging like this.

realm.beginWrite()
let m = realm.objects(Inventory.self).filter("id == %@", detailId as Any).first
m!.image = nil
try! realm.commitWrite()

// Inventory.swift

class Inventory: Object {
@objc dynamic var number: Int = 1

//ID
@objc dynamic var id = 0

//Image
@objc dynamic private var imageData: Data? = nil 
dynamic private var _image: UIImage? = nil  

dynamic var image: UIImage? {
    set{
        self._image = newValue
        if let value = newValue {
            self.imageData = value.pngData() as Data?
        }
    }
    get{
        if let image = self._image {
            return image
        }
        if let data = self.imageData {
            self._image = UIImage(data: data as Data)
            return self._image
        }
        return nil
    }
} }
Jay

The problem with the code in the question is how the Inventory objects image property is being set to nil.

When this happens

m!.image = nil

It's setting the unmanaged image property to nil

set {
   self._image = newValue
   if let value = newValue {
      self.imageData = value.pngData() as Data?
   }
}

But as you can see with the if statement within set, if the value is nil, it's ignored, so self.imageData is never set to nil

There are a lot of solutions but since all of those vars are optionals, probably the simplest is to just let it be nil within the set

set {
   self._image = newValue
   self.imageData = newValue.pngData() as Data?
}

EDIT

the below is the original answer but once more data was added the the question it was not complete.

Only optional properties can be set to nil. So they need to be defined in a special way in realm, like this for a String object

class Inventory: Object {
   @objc dynamic var id = ""
   @objc dynamic var imageName: String? = nil  //or NSData/Data
   //or for numbers, use this let value = RealmOptional<Int>()
   ...

then to set the optional to nil something like this is a safe way to do it

let detailId = "some detail id"
if let item = realm.objects(Inventory.self).filter("id == %@", detailId).first {
    try! realm.write {
        item.imageName = nil
    }
} else {
  print("item not found")
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related