ray
ray

Reputation: 102

Sending SMS from Contacts Fails

I am implementing a seemingly trivial and very popular use case where users select a contact, and send them a precomposed SMS.

However, the SMS ViewController dismisses itself automatically. This is easily reproducible.

How do I fix this?

Here's my code:

import UIKit
import MessageUI
import ContactsUI

class ViewController: UIViewController, MFMessageComposeViewControllerDelegate, CNContactPickerDelegate{

    let contactPickerViewController = CNContactPickerViewController()
    let messageVC = MFMessageComposeViewController()

    override func viewDidLoad() {
        super.viewDidLoad()
        contactPickerViewController.delegate = self

        messageVC.messageComposeDelegate = self
    }

    func contactPicker(picker: CNContactPickerViewController, didSelectContact contact: CNContact) {
        if let phoneNumberValue = contact.phoneNumbers.first?.value as? CNPhoneNumber {
            if let phoneNumber = phoneNumberValue.valueForKey("digits") as? String {

                // Configure message ViewController
                messageVC.recipients = [phoneNumber]
                messageVC.body = "Yoyoyo"

                picker.presentViewController(messageVC, animated: true, completion: nil)
            }
        }
    }

    func messageComposeViewController(controller: MFMessageComposeViewController, didFinishWithResult result: MessageComposeResult) {
        self.dismissViewControllerAnimated(true, completion: nil)
    }

    @IBAction func invite(sender: AnyObject) {
        self.presentViewController(self.contactPickerViewController, animated: true, completion: nil)

    }
}

Upvotes: 4

Views: 328

Answers (1)

Chris
Chris

Reputation: 1750

The problem is that you are asking your picker to present the message view controller. When contactPicker:picker:didSelectContact: method is called, the picker view controller is automatically being dismissed by the system. This means that the view controller is going away and you are trying to use that view controller to present your next view controller.

What you need to do is have "ViewController" in this case present the message view controller. Below is an example of the portion of your code i changed. You'll notice i have a timer there. This is because if you try to present the messageVC right away, nothing will happen because the contacts view controller isn't done dismissing itself yet.

func contactPicker(picker: CNContactPickerViewController, didSelectContact contact: CNContact) {
    if let phoneNumberValue = contact.phoneNumbers.first?.value as? CNPhoneNumber {
        if let phoneNumber = phoneNumberValue.valueForKey("digits") as? String {

            // Configure message ViewController
            messageVC.recipients = [phoneNumber]
            messageVC.body = "Yoyoyo"

            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                self.presentViewController(self.messageVC, animated: true, completion: nil)
            })
        }
    }
}

Upvotes: 3

Related Questions