대부분의 모바일 애플리케이션에는 콘텐츠를 공유하는 기능이 기본적으로 탑재되어 있습니다. 따라서 iOS 앱에서 이메일에 첨부 파일을 담아 전송하는 방법을 익혀두는 것은 개발자에게 매우 중요한 역량입니다.
이 글에서는 Swift를 사용하여 이메일에 첨부 파일을 추가하고 전송하는 방법을 단계별로 살펴보겠습니다.
핵심 클래스: MFMailComposeViewController
이번 예제에서는 MFMailComposeViewController를 사용합니다. 이는 Apple이 기본 제공하는 표준 뷰 컨트롤러로, 사용자가 이메일 메시지를 작성·편집·관리하고 전송할 수 있는 인터페이스를 제공합니다.
자세한 사항은 Apple 공식 문서(MFMailComposeViewController)에서 확인할 수 있습니다.
또한 MFMailComposeViewControllerDelegate 프로토콜을 함께 채택하여 메일 전송 결과(MFMailComposeResult)를 처리하게 됩니다. 관련 문서는 여기에서 확인하세요.
그럼 샘플 앱을 직접 만들어 보며 하나씩 알아보겠습니다.
단계별 구현 가이드
1단계: Xcode 프로젝트 생성
Xcode를 실행한 뒤 → Single View Application → 프로젝트 이름을 'EmailAttachment'로 지정합니다.
2단계: 스토리보드에 버튼 추가
Main.storyboard를 열고 아래 이미지와 같이 'send mail'이라는 이름의 버튼을 하나 배치합니다.

3단계: IBAction 생성
버튼과 연결할 @IBAction을 만들고 이름을 btnSendMail로 지정합니다.
@IBAction func btnSendMail(_ sender: Any) { }4단계: MessageUI 임포트
ViewController.swift 상단에 MessageUI를 임포트합니다.
import MessageUI
5단계: 델리게이트 프로토콜 채택
ViewController 클래스가 MFMailComposeViewControllerDelegate를 채택하도록 선언합니다.
class ViewController: UIViewController, MFMailComposeViewControllerDelegate
6단계: 첨부 파일 프로젝트에 추가
첨부할 파일(예: sampleData.json)을 프로젝트에 드래그 앤 드롭으로 추가합니다.

7단계: 메일 전송 로직 작성
btnSendMail 함수 안에 아래 코드를 작성합니다.
@IBAction func btnSendMail(_ sender: Any) {
if MFMailComposeViewController.canSendMail() {
let mail = MFMailComposeViewController()
mail.setToRecipients(["test@gmail.com"])
mail.setSubject("GREETING")
mail.setMessageBody("Welcome to Tutorials Point!", isHTML: true)
mail.mailComposeDelegate = self
// 첨부 파일 추가
if let filePath = Bundle.main.path(forResource: "sampleData", ofType: "json") {
if let data = NSData(contentsOfFile: filePath) {
mail.addAttachmentData(data as Data, mimeType: "application/json", fileName: "sampleData.json")
}
}
present(mail, animated: true)
} else {
print("Email cannot be sent")
}
}여기까지 하면 기본 구현은 완료입니다! 하지만 실제 앱에서는 메일이 성공적으로 전송되었는지, 사용자가 취소했는지, 전송에 실패했는지 같은 다양한 상황도 처리해야 합니다. 바로 그렇기 때문에 앞서 델리게이트 프로토콜을 채택한 것입니다.
전송 결과 처리하기
델리게이트 메서드를 구현하여 각 상태별로 결과를 처리해 보겠습니다.
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
if let _ = error {
self.dismiss(animated: true, completion: nil)
}
switch result {
case .cancelled:
print("Cancelled")
break
case .sent:
print("Mail sent successfully")
break
case .failed:
print("Sending mail failed")
break
default:
break
}
controller.dismiss(animated: true, completion: nil)
}이제 정말 완성입니다! 시뮬레이터가 아닌 실제 기기에서 프로그램을 실행해 확인해 보세요.

전체 코드
import UIKit
import MessageUI
class ViewController: UIViewController, MFMailComposeViewControllerDelegate {
override func viewDidLoad() {
}
@IBAction func btnSendMail(_ sender: Any) {
if MFMailComposeViewController.canSendMail() {
let mail = MFMailComposeViewController()
mail.setToRecipients(["test@gmail.com"])
mail.setSubject("GREETING")
mail.setMessageBody("Welcome to Tutorials Point!", isHTML: true)
mail.mailComposeDelegate = self
if let filePath = Bundle.main.path(forResource: "sampleData", ofType: "json") {
if let data = NSData(contentsOfFile: filePath) {
mail.addAttachmentData(data as Data, mimeType: "application/json", fileName: "sampleData.json")
}
}
present(mail, animated: true)
} else {
print("Email cannot be sent")
}
}
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
if let _ = error {
self.dismiss(animated: true, completion: nil)
}
switch result {
case .cancelled:
print("Cancelled")
break
case .sent:
print("Mail sent successfully")
break
case .failed:
print("Sending mail failed")
break
default:
break
}
controller.dismiss(animated: true, completion: nil)
}
}
참고: MFMailComposeViewController는 시뮬레이터에서 동작하지 않으므로 반드시 실제 iPhone 기기에서 테스트해야 하며, 기기에 메일 계정이 미리 설정되어 있어야 canSendMail()이 true를 반환합니다.