skip to Main Content

Hi I’m trying to change the variable ‘category’ from an object called ‘book’ in realm with the following code:

                  alert.addAction(UIAlertAction(title: "Reading", style: .default, handler: { (_) in
                try! realm.write {
                     let category = "reading"
                            let book = Book()
                            book.category = category
                   }
              }

When I checked in mangoDB realm studio the object category has not been updated. The tutorials I looked at used the same function. This is the whole updated code:

  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    func showmethisfunction() {
        let realm = try! Realm()
        let boook = Book()
        
        
        let alert = UIAlertController(title: "Want to put your book in a list?", message: "Please Select an Option", preferredStyle: .actionSheet)

        alert.addAction(UIAlertAction(title: "Read", style: .default, handler: { (_) in
                 try! realm.write
                {
                    boook.category = "read"
                   }
              }))

              alert.addAction(UIAlertAction(title: "Want to read", style: .default, handler: { (_) in
                try! realm.write {
                    boook.category = "wanttoread"
                   }
              }))

              alert.addAction(UIAlertAction(title: "Reading", style: .default, handler: { (_) in
                try! realm.write {
                    let category = "reading"
                    boook.category = category
                   }
              }))

              alert.addAction(UIAlertAction(title: "Dismiss", style: .cancel, handler: { (_) in
                  print("User click Dismiss button")
              }))

              self.present(alert, animated: true, completion: {
                  print("completion block")
              })
    }
showmethisfunction()
}

I used a similiar alert controller to add a book manually, and that worked, it just doesn’t work when I want to add a variable from a book

3

Answers


  1. First get your object which one you can update.
    I’m given example using filter. You can use any.

    do {
         let realm = try Realm()
         let book = realm.objects(Book.self).filter({ $0.id == id }).first
            try realm.write {
                book?.category = category
            }
        } catch { }
    

    Or get idea from this link
    https://docs.mongodb.com/realm-legacy/docs/swift/latest/index.html#models

    Go to Auto-updating objects section in above link.

    I updated my answer after updated your question.
    Replace line
    let boook = Book() with this line
    let boook = realm.objects(Book.self).first ?? Book()

    Login or Signup to reply.
  2. To restate the question:

    How do I updated a property on an existing object

    There are a number of different ways to do that and some of the answer depends on the object model.

    Generally speaking, most objects would have some unique identifier called the primary key and if you know that identifier, updating the object is a snap

    class PersonClass: Object {
        @objc dynamic var _id = ObjectId.generate()
        @objc dynamic var name = "Jay"
    
        override static func primaryKey() -> String? {
            return "_id"
        }
    }
    

    The ObjectId will generate a unique _id for every object when it’s instantiated. If you know the primary key, you can update an object like this

    try! realm.write {
        realm.create(PersonClass.self, value: ["id": "1", "name": "Jay 2"], update: .modified)
    }
    

    This assumes the existing object you want to update has a primary key of "1" and will update the object’s name property to Jay 2

    You can also read the object in via the primary key to then update it

    if let jay = realm.object(ofType: PersonClass.self, forPrimaryKey: "1") {
        try! realm.write {
            jay.name = "Jays new name"
        }
    }
    

    lastly you can run a query to get an object with a matching property as well (but don’t do this)

    if let jay = realm.objects(PersonClass.self).filter("name == 'Jay'").first {
        try! realm.write {
            jay.name = "Jays new name"
        }
    }
    

    This last option is generally a bit ‘dangerous’ as it will filter for all PersonClass objects with the name of ‘Jay’ and the results will be unordered so the first one could be different at different times… so the key here is ‘don’t do it this way’.

    As a side note per the above, realm results are unordered unless you specify the .sorted(byKeyPath:.

    Login or Signup to reply.
  3. You can update the existing object without creating primary key in RealmSwift.

    1. Create the keys of the Realm Object.

    import Foundation
    import RealmSwift

    final class ModelRealM: Object {

    @objc dynamic var message = String()
    @objc dynamic var type = String()
    

    }

    1. In ViewController create array variable of type (var arrData : Results!)

    class ChattingVC: UIViewController {

    let chattingVM = ChattingVM()

    let realm = try! Realm()

    var arrData : Results!

    //MARK: - View Life Cycle
    override func viewDidLoad() {
        super.viewDidLoad()
        
        arrData = realm.objects(ModelRealM.self)
        var model = ModelRealM()
        
        model.message = "ABC"
        model.type = "Text"
        
        self.chattingVM.saveData(model) { isDone in
            
            if isDone{
                
                self.tableView.reloadData()
                
            }
            
        }
        
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return chattingVM.realm.objects(ModelRealM.self).count
        
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        guard let type = arrData?[indexPath.row].type else{
            
            print("------------No Data found------------")
            return UITableViewCell()
            
        }
        if type == "Receiver"{
            
            let cell = tableView.dequeueReusableCell(withIdentifier: "ReceiverCell", for: indexPath) as! ReceiverCell
            cell.model = arrData?[indexPath.row]
            cell.editBtn.tag = indexPath.row
            cell.editBtn.addTarget(self, action: #selector(self.editReceiverBtn(sender:)), for: .touchUpInside)
            return cell
            
        }else{
            
            let cell = tableView.dequeueReusableCell(withIdentifier: "SenderCell", for: indexPath) as! SenderCell
            cell.model = arrData?[indexPath.row]
            cell.editBtn.tag = indexPath.row
            cell.editBtn.addTarget(self, action: #selector(self.editReceiverBtn(sender:)), for: .touchUpInside)
            return cell
            
        }
        
    }
    
    @objc func editReceiverBtn(sender:UIButton){
        
        self.txtView.text = "" //Write the updated message in TxtView and pass in this function.
        self.chattingVM.updateReamObject(index: sender.tag, msg: self.txtView.text) { isTrue in
            
            if isTrue{
                
                self.tableView.reloadData()
                
            }
            
        }
        
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }
    

    }

    1. In View Model Update Function is used to update

    class ChattingVM{

    //MARK: - Variables
    let realm = try! Realm()
    
    //MARK: -
    //MARK: - Save Data to Realm
    func saveData(_ data : ModelRealM,completion:@escaping(_ isDone: Bool) -> Void){
       
        do{
            try realm.write {
                realm.add(data)
            }
        }catch{
            print("Error in saving data :- (error.localizedDescription)")
        }
        
        completion(true)
        
    }
    
    
    //MARK: -
    //MARK: - Update Data
    func updateReamObject(index:Int,msg:String,completion:@escaping(_ isTrue:Bool) -> Void){
        
        do{
            try realm.write {
                realm.objects(ModelRealM.self)[index].message = msg
            }
        }catch{
            print("Error in saving data :- (error.localizedDescription)")
        }
        
        completion(true)
        
    }
        
    

    }

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search