Swift
Mail App
iOS Development
Programming Tutorial
Apple Development

How to open mail app from Swift

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

In iOS, "open the Mail app" can mean two different things: launch the Mail application itself, or present an email composer inside your app. Swift supports both paths, and the right choice depends on whether you want the user to leave your app or stay inside it.

Open Mail With a mailto: URL

If you want to hand the user off to the Mail app, use a mailto: URL. This is the direct way to launch the system mail flow.

swift
1import UIKit
2
3func openMailApp() {
4    guard let url = URL(string: "mailto:[email protected]") else { return }
5
6    if UIApplication.shared.canOpenURL(url) {
7        UIApplication.shared.open(url, options: [:], completionHandler: nil)
8    }
9}

This opens Mail and pre-fills the recipient. You can also include a subject or body:

swift
1func openMailAppWithDraft() {
2    let subject = "Bug report".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
3    let body = "Describe the problem here.".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
4
5    let raw = "mailto:[email protected]?subject=\(subject)&body=\(body)"
6    guard let url = URL(string: raw) else { return }
7
8    UIApplication.shared.open(url)
9}

This is simple, but once the Mail app opens, your app no longer controls the compose experience.

Present an In-App Mail Composer

If you want users to stay inside your app, use MFMailComposeViewController from MessageUI.

swift
1import MessageUI
2import UIKit
3
4final class SupportViewController: UIViewController, MFMailComposeViewControllerDelegate {
5    func sendMail() {
6        guard MFMailComposeViewController.canSendMail() else {
7            return
8        }
9
10        let composer = MFMailComposeViewController()
11        composer.mailComposeDelegate = self
12        composer.setToRecipients(["[email protected]"])
13        composer.setSubject("Support Request")
14        composer.setMessageBody("Hello team,", isHTML: false)
15
16        present(composer, animated: true)
17    }
18
19    func mailComposeController(
20        _ controller: MFMailComposeViewController,
21        didFinishWith result: MFMailComposeResult,
22        error: Error?
23    ) {
24        controller.dismiss(animated: true)
25    }
26}

This does not literally "open Mail," but it is often the better user experience because the compose UI stays inside your app and supports attachments.

Handle Fallbacks Gracefully

Not every device can send mail. The user may have removed the Mail app, or Mail may exist but no account may be configured for composing messages inside the app. For that reason, production code should always have a fallback.

A simple pattern is:

  1. Try MFMailComposeViewController if you want in-app composition.
  2. Fall back to mailto: if you are comfortable leaving the app.
  3. If neither route is available, show the email address and let the user copy it.

That gives you a reliable support flow instead of a dead tap.

Which Approach Should You Use

Choose mailto: when:

  • You specifically want the Mail app to open
  • A simple compose handoff is enough
  • You do not need attachments or in-app result handling

Choose MFMailComposeViewController when:

  • You want to stay inside your app
  • You need richer draft control
  • You want to react to cancel, save, send, or failure events

The title of the question usually points to mailto:, but many real apps actually need the in-app composer instead.

Common Pitfalls

  • Assuming mailto: guarantees Mail is configured can lead to dead-end behavior on devices without a mail account set up.
  • Forgetting percent-encoding breaks subjects and bodies that contain spaces or punctuation.
  • Presenting MFMailComposeViewController without checking canSendMail() causes a poor user experience on unsupported devices.
  • Expecting MFMailComposeViewController to launch the standalone Mail app is a misunderstanding; it presents Apple's compose UI inside your app.

Summary

  • Use a mailto: URL when you want to open the Mail app directly.
  • Use MFMailComposeViewController when you want email composition inside your app.
  • Add a fallback so the user can still reach the address when Mail is unavailable.
  • Percent-encode query values in mailto: links and always check capability before presenting the in-app composer.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.