Search code examples
swiftmfmessagecomposeviewcontrollercncontactcncontactviewcontroller

Cannot convert type '[String: Any Object]' to expected type 'String'


Trying to get the phone number string out of CNContacts. I pull up a contact picker view controller and when the user selects multiple contacts, I create a message compose view controller. I need to create an array of strings to pass along as the recipients of the message compose view controller. Error comes from the following line...contactsPhoneNumber.append(phoneNumber)

func AddFriendTapped() {
    let contactPickerViewController = CNContactPickerViewController()
    contactPickerViewController.delegate = self
    presentViewController(contactPickerViewController, animated: true, completion: nil)
}


func contactPicker(picker: CNContactPickerViewController,didSelectContacts contacts: [CNContact]) {

    //check if phone can send texts, if so, continue
    if !MFMessageComposeViewController.canSendText(){

        let composeVC = MFMessageComposeViewController()
        composeVC.messageComposeDelegate = self

        //must get phone number strings from CNContact
        let phoneNumberKey = [CNContactPhoneNumbersKey]
        for contact in contacts {
            var phoneNumber = contact.dictionaryWithValuesForKeys(phoneNumberKey)
            contactsPhoneNumber.append(phoneNumber)
        }

        composeVC.recipients = contactsPhoneNumber
        composeVC.body = "Hi, test message"

        // Present the view controller modally.
        dismissViewControllerAnimated(true) {
            self.presentViewController(composeVC, animated: true, completion: nil)
        }

    }

}

func messageComposeViewController(controller: MFMessageComposeViewController,
                                  didFinishWithResult result: MessageComposeResult) {
    // Check the result or perform other tasks.

    // Dismiss the mail compose view controller.
    controller.dismissViewControllerAnimated(true, completion: nil)
}

Solution

  • A contact can have multiple phone numbers so contact.phoneNumbers returns an array of CNlabeledValue. You need two loops, one to iterate all the contacts other to iterate all the numbers. Then you have to extract the phone number which is of type CNPhoneNumber and then convert it to string.

    I have made some changes in your code. Hope it helps. :)

    func contactPicker(picker: CNContactPickerViewController,didSelectContacts contacts: [CNContact]) {
    
        //check if phone can send texts, if so, continue
        if !MFMessageComposeViewController.canSendText(){
    
            let composeVC = MFMessageComposeViewController()
            composeVC.messageComposeDelegate = self
    
            //must get phone number strings from CNContact
    
            //let phoneNumberKey = [CNContactPhoneNumbersKey]
    
    
            for contact in contacts {
                let contactNumberArray = contact.phoneNumbers
                for contactNumber in contactNumberArray{
                    let number = contactNumber.value as! CNPhoneNumber
                    contactsPhoneNumber.append(number.stringValue)
                }
            }
    
    
            composeVC.recipients = contactsPhoneNumber
            composeVC.body = "Hi, test message"
    
            // Present the view controller modally.
            dismissViewControllerAnimated(true) {
                self.presentViewController(composeVC, animated: true, completion: nil)
            }
    
        }
    
    }