How to Send SMS and MMS From iOS Using MessageUI

Send SMS and MMS from iOS apps using MFMessageComposeViewController from the MessageUI framework. The message composer presents the same interface as Apple's native Messages app. You configure recipients, message body, and optional file attachments. A delegate callback reports the send result. For simpler scenarios, the sms URL scheme opens Messages directly with pre-filled content.

What Is MFMessageComposeViewController

MFMessageComposeViewController is a system-provided view controller for composing text messages. It supports SMS for text-only messages and MMS for messages with file attachments. The interface matches the native Messages app. Users get a familiar experience without leaving your application.

How to Set Up the Message Composer Delegate

Import MessageUI and implement the delegate:

import MessageUI

extension AttachmentTableViewController: MFMessageComposeViewControllerDelegate {
    func messageComposeViewController(_ controller: MFMessageComposeViewController,
                                        didFinishWith result: MessageComposeResult) {
        switch result {
        case .cancelled:
            print("SMS cancelled")
        case .failed:
            let alert = UIAlertController(title: "Failure",
                                          message: "Failed to send the message.",
                                          preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "OK", style: .default))
            present(alert, animated: true)
        case .sent:
            print("SMS sent successfully")
        @unknown default:
            print("Unknown error")
        }
        dismiss(animated: true, completion: nil)
    }
}

The delegate handles three scenarios. Cancelled means the user dismissed the composer. Sent means the message was delivered. Failed indicates a delivery error. Show an alert for failures instead of silent logging.

How to Compose and Send an SMS

Check capability and present the composer:

private func sendSMS() {
    guard MFMessageComposeViewController.canSendText() else {
        let alert = UIAlertController(title: "SMS Unavailable",
                                      message: "Your device cannot send SMS.",
                                      preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        present(alert, animated: true)
        return
    }
    
    let messageController = MFMessageComposeViewController()
    messageController.messageComposeDelegate = self
    messageController.recipients = ["12345678", "72345524"]
    messageController.body = "Check out this content!"
    
    present(messageController, animated: true, completion: nil)
}

MFMessageComposeViewController.canSendText returns false on iPod touch without iMessage, iPad without iMessage account, and the simulator. Always call this check before presenting the composer.

How to Add File Attachments for MMS

Extend the sendSMS method with file attachments:

private func sendSMS(attachment: String) {
    guard MFMessageComposeViewController.canSendText() else {
        return
    }
    
    let messageController = MFMessageComposeViewController()
    messageController.messageComposeDelegate = self
    messageController.recipients = ["12345678", "72345524"]
    messageController.body = "Check out this (attachment)!"
    
    let fileparts = attachment.components(separatedBy: ".")
    let filename = fileparts[0]
    let fileExtension = fileparts[1]
    let filePath = Bundle.main.path(forResource: filename, ofType: fileExtension)
    let fileUrl = NSURL.fileURL(withPath: filePath!)
    messageController.addAttachmentURL(fileUrl, withAlternateFilename: nil)
    
    present(messageController, animated: true, completion: nil)
}

addAttachmentURL attaches the file at the specified URL. The optional alternateFilename renames the attachment for the recipient. The system automatically converts the message to MMS when an attachment is present. MMS requires a data connection or MMS-enabled carrier plan.

SMS vs MMS Differences

SMS supports text only with 160 characters per segment. MMS supports images, videos, audio, and documents. SMS works on any phone. MMS requires a data connection or MMS-enabled carrier plan. When you add an attachment, the system converts the message to MMS automatically.

How to Use the SMS URL Scheme as an Alternative

Open the native Messages app with pre-filled content using URL schemes:

if let messageUrl = URL(string: "sms:123456789&body=Hello") {
    UIApplication.shared.open(messageUrl, options: [:], completionHandler: nil)
}

The sms scheme opens Messages with the specified recipient. The body parameter pre-fills the message content. This approach requires zero code beyond URL construction. Users get the full Messages app experience. It works on devices that cannot send SMS because iMessage-only devices can still open the app. Use ampersand as the parameter separator between recipient and body.

When to Use In-App Composer vs URL Scheme

Use the in-app MFMessageComposeViewController for deep integration with delivery confirmation and enforcement of specific message content. Use the sms URL scheme for simple sharing actions where delivery confirmation is not required and users prefer navigating to the Messages app.

Advanced Configuration Options

Set multiple recipients with country codes for international delivery:

messageController.recipients = ["+1234567890", "+1987654321"]

Add a subject line that appears in the conversation list:

messageController.subject = "Important Document"

Check specific capabilities before using advanced features:

MFMessageComposeViewController.canSendSubject()
MFMessageComposeViewController.canSendAttachments()

Best Practices for SMS and MMS Integration

Always check canSendText first and present a fallback such as email when SMS is unavailable. Pre-populate recipients and body but never auto-send. Users must tap Send manually. Handle the failure case with a friendly alert that offers retry options. Respect carrier costs as SMS and MMS may incur charges for users. Test on multiple devices including iPhone with cellular plan and iPad with iMessage only. Keep messages concise as SMS segments are limited to 160 characters. Longer messages are concatenated but may incur additional charges.

Summary

This tutorial covered the complete implementation process from setup to working code. You now have a functional implementation that you can extend and customize for your own projects. The same patterns apply to related features in the iOS ecosystem.

Frequently Asked Questions

Can I test this on the iOS Simulator? Some features require a physical device with a compatible processor. The article notes specific sections where the Simulator is sufficient and where a real device is required.

What are the prerequisites for this tutorial? You need Xcode installed on a Mac and basic familiarity with Swift programming. No prior experience with the specific framework is required.

All articles