Search code examples
swiftmfmessagecomposeviewcontroller

error appears when I try to present message format?


I try to present message format in main menu class from emergency class, but it doesn't present anything and this what Xcode keep telling me

Warning: Attempt to present <MFMessageComposeViewController: 0x13703dc00> on <Emergency: 0x1365a4b60> whose view is not in the window hierarchy!
Warning: Attempt to present <MFMessageComposeViewController: 0x13703dc00>  on <MainMenu: 0x136649fd0> which is already presenting (null)

here's the code

MainMenu class

class MainMenu: UIViewController{

    let getHelp:Emergency = Emergency()
    @IBAction func TapOnEmergency(sender: UIButton) {


         getHelp.emergencyMessage()

        getHelp.presentViewController(getHelp.messageComposer,animated: false,completion: nil)

        dispatch_async(dispatch_get_main_queue(), {
            self.presentViewController(self.getHelp.messageComposer, animated: true, completion: nil)
        })
    }
    }

Emergency class

class Emergency: UIViewController,MFMessageComposeViewControllerDelegate{

    func emergencyMessage()
    {

         let textMessageRecipients = [number!]



                if (MFMessageComposeViewController.canSendText() ) {
                    messageComposer.recipients = textMessageRecipients
                    messageComposer.body = ""
                    messageComposer.messageComposeDelegate = self
                   presentViewController(messageComposer,animated: false,completion: nil)

        } else {

    let errorAlert = UIAlertController(title: "Cannot Send Text Message", message: "Your device is not able to send text messages.", preferredStyle: UIAlertControllerStyle.Alert)

    errorAlert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Cancel, handler: nil))

    self.presentViewController(errorAlert, animated: true, completion: nil)

        }


    }

How I can fix this problem?

note that emergency has no scene/view


Solution

  • The Emergency class should not inherit from UIViewController since it is not a view controller and does not manage a view. However, it needs to be able to present a view controller itself, so it needs to be passed in one. Therefore your MainMenu becomes:

    class MainMenu: UIViewController {
        let getHelp:Emergency = Emergency()
        @IBAction func TapOnEmergency(sender: UIButton) {
            getHelp.emergencyMessage(self)
        }
    }
    

    And the Emergency class becomes:

    class Emergency: NSObject, MFMessageComposeViewControllerDelegate {
        func emergencyMessage(vc: UIViewController)
        {
             let textMessageRecipients = [number!]
             if (MFMessageComposeViewController.canSendText() ) {
                 messageComposer.recipients = textMessageRecipients
                 messageComposer.body = ""
                 messageComposer.messageComposeDelegate = self
                 vc.presentViewController(messageComposer, animated: false,completion: nil)
             } else {
                 let errorAlert = UIAlertController(title: "Cannot Send Text Message", message: "Your device is not able to send text messages.",                 preferredStyle: UIAlertControllerStyle.Alert)
                 errorAlert.addAction(UIAlertAction(title: "OK", style:  UIAlertActionStyle.Cancel, handler: nil))
                vc.presentViewController(errorAlert, animated: true, completion: nil)
             }
        }
    }