【Swift】アプリ内でメーラーを起動しメール送信するやり方

#はじめに
アプリ内でメーラーを起動させ、
CSVファイルを添付したメールを送信したいと思い、実装しました。
今回は、アプリ内でメーラーを起動してメール送信するやり方をまとめました。

#手順
1. MessageUIフレームワークを追加する
2. MessageUIをimportする
3. MFMailComposeViewControllerインスタンスを生成し、宛先や本文などを設定する
4. MFMailComposeViewControllerDelegateで終了処理を実装する
 

#1. フレームワークの追加
[フレームワーク追加に関する参考サイト](http://techacademy.jp/magazine/2703)
まず、プロジェクトに**MessageUIフレームワーク**を追加します。
 
①ナビゲーションエリアのプロジェクト名が書かれている項目をクリックし、
　**BuildPhases**の項目をクリックします。下記画像参照。
![スクリーンショット 2015-05-01 16.51.36.png](https://qiita-image-store.s3.amazonaws.com/0/75241/21115884-222f-9cb3-394a-bcebb2359680.png)

②**Link Binary with Libraries**の**+**マークをクリックする。
　検索欄に**MessageUI**と入力すると**MessageUI.framework**が出てくる。
　**MessageUI.framework**を選択し、**Add**をクリックする。下記画像参照。
![スクリーンショット 2015-05-01 16.52.12.png](https://qiita-image-store.s3.amazonaws.com/0/75241/a3b3bc27-880e-c57d-a7de-d301ecda5aa1.png)

③そうすると、**Link Binary with Libraries**に**MessageUI.framework**が追加されている。
　下記画像参照。
![スクリーンショット 2015-05-01 16.52.20.png](https://qiita-image-store.s3.amazonaws.com/0/75241/090ef514-7aa0-84c4-f3b8-e8f108e6f129.png)

#2. 準備
`import MessageUI`を追加する。
終了処理を実装するために、`MFMailComposeViewControllerDelegate`を追加する。

```ViewController.swift
import UIKit
import MessageUI

class ViewController: UIViewController, MFMailComposeViewControllerDelegate{

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}
```

#3. ボタンをクリックしたらメーラーが起動するようにする
## 3-1. ボタンの作成
適当にボタンを作成します。(以下、storyboardは使用しないで作成しています)

**ViewController.swift**に`let startMailerBtn = UIButton(frame: CGRectMake(0,0,200,30))`を追加します。
そして、**viewDidLoad()**に以下を追加します。

```swift
startMailerBtn.layer.position = CGPoint(x:self.view.bounds.width/2,y:y:self.view.bounds.height/2);
startMailerBtn.setTitle("メール送信", forState: .Normal)
startMailerBtn.setTitleColor(UIColor.blueColor(), forState: .Normal)
startMailerBtn.addTarget(self, action: "onClickStartmailerBtn:", forControlEvents: .TouchUpInside)
self.view.addSubview(startMailerBtn)
```
↓全体

```ViewController.swift
import UIKit
import MessageUI

class ViewController: UIViewController, MFMailComposeViewControllerDelegate{

    let startMailerBtn = UIButton(frame: CGRectMake(0,0,200,30))
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        startMailerBtn.layer.position = CGPoint(x:self.view.bounds.width/2,y:y:self.view.bounds.height/2);
        startMailerBtn.setTitle("メール送信", forState: .Normal)
        startMailerBtn.setTitleColor(UIColor.blueColor(), forState: .Normal)
        startMailerBtn.addTarget(self, action: "onClickStartMailerBtn:", forControlEvents: .TouchUpInside)
        self.view.addSubview(startMailerBtn)
        
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}
```
これで"メール送信"という名前のボタンを表示できました。
![sample1.png](https://qiita-image-store.s3.amazonaws.com/0/75241/0050bc7d-e2a6-20fb-f664-a783561b75f8.png)



##3-2. ボタンをクリックしたらメーラーが起動する処理
ボタンがクリックされた時の処理を追加するために、
まず**ViewController.swift**に`onClickStartMailerBtn関数`を追加します。
その中に、以下を追加します。

```swift
//メールを送信できるかチェック
if MFMailComposeViewController.canSendMail()==false {
    println("Email Send Failed")
    return
}

var mailViewController = MFMailComposeViewController()
var toRecipients = ["to@1gmail.com"] //Toのアドレス指定
var CcRecipients = ["cc@1gmail.com","Cc2@1gmail.com"] //Ccのアドレス指定
var BccRecipients = ["Bcc@1gmail.com","Bcc2@1gmail.com"] //Bccのアドレス指定
       
mailViewController.mailComposeDelegate = self
mailViewController.setSubject("メールの件名")
mailViewController.setToRecipients(toRecipients) //Toアドレスの表示
mailViewController.setCcRecipients(CcRecipients) //Ccアドレスの表示
mailViewController.setBccRecipients(BccRecipients) //Bccアドレスの表示
mailViewController.setMessageBody("メールの本文", isHTML: false)
self.presentViewController(mailViewController, animated: true, completion: nil)
```

↓全体

```ViewController.swift
import UIKit
import MessageUI

class ViewController: UIViewController, MFMailComposeViewControllerDelegate{

    let startMailerBtn = UIButton(frame: CGRectMake(0,0,200,30))
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        startMailerBtn.layer.position = CGPoint(x:self.view.bounds.width/2,y:self.view.bounds.height/2);
        startMailerBtn.setTitle("メール送信", forState: .Normal)
        startMailerBtn.setTitleColor(UIColor.blueColor(), forState: .Normal)
        startMailerBtn.addTarget(self, action: "onClickStartMailerBtn:", forControlEvents: .TouchUpInside)
        self.view.addSubview(startMailerBtn)
        
    }

    func onClickStartMailerBtn(sender: UIButton) {
        //メールを送信できるかチェック
        if MFMailComposeViewController.canSendMail()==false {
            println("Email Send Failed")
            return
        }
        
        var mailViewController = MFMailComposeViewController()
        var toRecipients = ["to@1gmail.com"]
        var CcRecipients = ["cc@1gmail.com","Cc2@1gmail.com"]
        var BccRecipients = ["Bcc@1gmail.com","Bcc2@1gmail.com"]
        
        
        mailViewController.mailComposeDelegate = self
        mailViewController.setSubject("メールの件名")
        mailViewController.setToRecipients(toRecipients) //Toアドレスの表示
        mailViewController.setCcRecipients(CcRecipients) //Ccアドレスの表示
        mailViewController.setBccRecipients(BccRecipients) //Bccアドレスの表示
        mailViewController.setMessageBody("メールの本文", isHTML: false)
        
        self.presentViewController(mailViewController, animated: true, completion: nil)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}
```
これで、ボタンを押したら以下のようにメーラーを表示させることが出来ました。
![sample2.png](https://qiita-image-store.s3.amazonaws.com/0/75241/61c67a9f-e42f-5660-9c28-5efce8d85db7.png)

もし、
メール本文に**画像**を表示させたい場合は、
以下のプログラムを`onClickStartMailerBtn関数`に
追加してあげれば下記の画像のようにメール本文に画像を表示できます。

```swift
var image = UIImage(named: "myphoto.png")
var imageData = UIImageJPEGRepresentation(image, 1.0)
mailViewController.addAttachmentData(imageData, mimeType: "image/png", fileName: "image")
```
![sample3.png](https://qiita-image-store.s3.amazonaws.com/0/75241/00fd5f27-5411-b3e3-953f-875fb8bb1322.png)


##3-3. 終了処理の追加
このままだと、SendやCancelをクリックしてもメール画面が閉じないため、
以下の閉じる処理を追加する。

```swift
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
        switch result {
        case .cancelled:
            print("Email Send Cancelled")
            break
        case .saved:
            print("Email Saved as a Draft")
            break
        case .sent:
            print("Email Sent Successfully")
            break
        case .failed:
            print("Email Send Failed")
            break
        default:
            break
        }
        controller.dismiss(animated: true, completion: nil)
    }
```
↓全体

```ViewController.swift
import UIKit
import MessageUI

class ViewController: UIViewController, MFMailComposeViewControllerDelegate{

    let startMailerBtn = UIButton(frame: CGRectMake(0,0,200,30))
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        startMailerBtn.layer.position = CGPoint(x:self.view.bounds.width/2,y:self.view.bounds.height/2);
        startMailerBtn.setTitle("メール送信", forState: .Normal)
        startMailerBtn.setTitleColor(UIColor.blueColor(), forState: .Normal)
        startMailerBtn.addTarget(self, action: "onClickStartMailerBtn:", forControlEvents: .TouchUpInside)
        self.view.addSubview(startMailerBtn)
        
    }

    func onClickStartMailerBtn(sender: UIButton) {
        //メールを送信できるかチェック
        if MFMailComposeViewController.canSendMail()==false {
            println("Email Send Failed")
            return
        }
        
        var mailViewController = MFMailComposeViewController()
        var toRecipients = ["to@1gmail.com"]
        var CcRecipients = ["cc@1gmail.com","Cc2@1gmail.com"]
        var BccRecipients = ["Bcc@1gmail.com","Bcc2@1gmail.com"]
        
        
        mailViewController.mailComposeDelegate = self
        mailViewController.setSubject("メールの件名")
        mailViewController.setToRecipients(toRecipients) //宛先メールアドレスの表示
        mailViewController.setCcRecipients(CcRecipients)
        mailViewController.setBccRecipients(BccRecipients)
        mailViewController.setMessageBody("メールの本文", isHTML: false)
        
        self.presentViewController(mailViewController, animated: true, completion: nil)
    }
    
    func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
        switch result {
        case .cancelled:
            print("Email Send Cancelled")
            break
        case .saved:
            print("Email Saved as a Draft")
            break
        case .sent:
            print("Email Sent Successfully")
            break
        case .failed:
            print("Email Send Failed")
            break
        default:
            break
        }
        controller.dismiss(animated: true, completion: nil)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}
```
これで、"メール送信"ボタンをクリックしたらメーラーが起動して、
メールを送信したりメール画面を閉じたりすることが出来ました。

#完成版ソースコード
https://github.com/chankei1/CSVAttachedToMailer
このリポジトリに後日csvファイルを添付できるプログラムも追加していこうと思っています。

#おわりに
今回は、**宛先メールアドレス**・**件名**・**本文の指定**をしてメーラーを起動し、
メール本文に**画像**を表示させてメール送信するところまでまとめました。
後日、このメールにアプリ内で生成したCSVファイルを自動添付するやり方をまとめようと思います。

#参考サイト
「MFMailComposeViewControllerでメールを送信する」
URL：http://www.mikamiz.jp/dev/iphone/a0005.html
「【swift】アプリ内でmailerを立ち上げてーバグリポート機能の実装【CoffeeNote開発記録】」
URL：http://totutotu.hatenablog.com/entry/2014/12/11/%E3%80%90swift%E3%80%91%E3%82%A2%E3%83%97%E3%83%AA%E5%86%85%E3%81%A7mailer%E3%82%92%E7%AB%8B%E3%81%A1%E4%B8%8A%E3%81%92%E3%81%A6%E3%83%BC%E3%83%90%E3%82%B0%E3%83%AA%E3%83%9D%E3%83%BC%E3%83%88%E6%A9%9F
「アプリから画像を添付してメールを送信する方法」
URL：http://www.crossbridge.biz/mfmailcomposeviewcontroller-with-image
「Stack Overflow(Failed on using Swift to implement in-app email)」
URL：http://stackoverflow.com/questions/24255270/failed-on-using-swift-to-implement-in-app-email