Search code examples
iosswiftuialertcontroller

Is this a bug in swift or my code is not correct(uialertcontroller)?


In this case I am using a uialertcontroller to inform user chose save , discard or cancel changes . but after the message appearing and before disappearing , the other code after that(makeNewDocument()) is executed. I am not sure is there a solution?

 @objc func deleteToNew(_ notification: Notification) {
    if AppDelegate.DocInEditing{
        let dialogMessage = UIAlertController(title: "Save changes?", message: "This file belongs to \(UserManager.shared.firstname)  \(UserManager.shared.lastname). Do you want to save changes?", preferredStyle: .alert)
        
                    let Yes = UIAlertAction(title: "Yes save", style: .default, handler: { (action) -> Void in
                        NotificationCenter.default.post(name: Notification.Name(rawValue: "saveChanges"), object: nil)
                        
                    })
                    let No = UIAlertAction(title: "No Discard changes", style: .default, handler: { (action) -> Void in
                    
                    })
                        
                    let cancel = UIAlertAction(title: "Cancel", style: .cancel) { (action) -> Void in
                    return
                    }
                    dialogMessage.addAction(Yes)
                    dialogMessage.addAction(No)
                    dialogMessage.addAction(cancel)
            present(dialogMessage, animated: true, completion: nil)
            
    }

    makeNewDocument()
    }

Solution

  • Is this a bug in swift

    No

    or my code is not correct(uialertcontroller)?

    Yes


    The alert controller and its actions work asynchronously, to run something on completion there is the completion parameter. Call it there

    present(dialogMessage, animated: true, completion: makeNewDocument)
    

    Or if you want to call makeNewDocument only in one of the actions, move the line into the action body

    let yes = UIAlertAction(title: "Yes save", style: .default, handler: { action in
                 NotificationCenter.default.post(name: Notification.Name(rawValue: "saveChanges"), object: nil)
                 self.makeNewDocument()                        
              })
    

    Side note:

    It's highly recommended to create Notification.Name constants only in an extension to take advantage of the safety of those constants

    extension Notification.Name {
        static let saveChanges = Notification.Name(rawValue: "saveChanges")
    }
    

    and use it

    let yes = UIAlertAction(title: "Yes save", style: .default, handler: { action in
                 NotificationCenter.default.post(name: .saveChanges, object: nil)
                 self.makeNewDocument()                        
              })