Presenting MFMessageComposeViewController/Understanding DispatchQueue.main.async

I'm trying to present the MFMessageComposeViewController after a person selects their contacts. But I'm getting the lldb error with the following message --

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modally an active controller <Indexex.PortfolioSettingsViewController: 0x1452000000>.'

Here's my code:

func contactPicker(_ picker: CNContactPickerViewController, didSelect contacts: [CNContact]) {
    var recipients = [String]()

    //-- select contacts and present message compose view controller
    contacts.forEach { (contact) in
        for data in contact.phoneNumbers {
            let phoneNo = data.value
            recipients.append(phoneNo.stringValue)
        }

        //-- configure message view controller
        messageViewController.recipients = recipients
        messageViewController.body = "Testing Testing"

        //-- reload the view controller
        DispatchQueue.main.async {
             self.present(self.messageViewController, animated: true, completion: nil)
        }
    }
}

I don't really understand that much about dispatch queue so I'm going to do way more research on that and threading but if anyone would be willing to help me out that would be greatly appreciated.

1 answer

  • answered 2018-07-11 06:23 Vinodh

    The problem is that you are attempting to show a message controller for each selected contact, at the same time. You can't do that. You can only show one at a time. Do you really want to show multiple message controllers, one for each contact, or one message with all of the contacts

    Since you try to present the multiple MFMessageComposeViewController, if you wanna single one call in outside for loop like below :

    contacts.forEach { (contact) in
        for data in contact.phoneNumbers {
            let phoneNo = data.value
            recipients.append(phoneNo.stringValue)
        }
    }
    
    //-- configure message view controller
    messageViewController.recipients = recipients
    messageViewController.body = "Testing Testing"
    
    //-- reload the view controller
    DispatchQueue.main.async {
         self.present(self.messageViewController, animated: true, completion: nil)
    }