質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1335閲覧

mailComposeController デリゲートメソッドが呼ばれない

sacakoro

総合スコア35

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

1クリップ

投稿2020/03/15 23:47

Xcode 11.2.1

MFMailComposeViewControllerのmailComposeController デリゲートメソッドが呼ばれず、解決に苦労しています。
アプリへの問い合わせ対応のために、画面のViewControllerとは別の、TOiawaseクラスにdelegateを設定しています。
メールの作成画面は表示できるのですが、メール送信後にメール作成画面が閉じません。

呼び出し側(端折りました)

Swift

1import UIKit 2import PKHUD 3import Common 4 5 6 7 8 9 10class ConfigTableViewController: UITableViewController , SKStoreProductViewControllerDelegate 11 // 2019.9.3 フォントと中央揃えを追加 start 12 ,UINavigationControllerDelegate, /*AdmobRewarder*/AdMobManagerRewarder,UIPopoverPresentationControllerDelegate,ColorPickerViewDelegate 13 // 2019.9.3 フォントと中央揃えを追加 end 14{ 15 16 var t : Toiawase? 17 18 19 var tapped:IndexPath = IndexPath(row: 0, section: 0) 20 21 22 23 override func viewDidLoad() { 24 super.viewDidLoad() 25 t = Toiawase(parent: self) 26 27 28 } 29 30 31 32 33 // セルがタップされた 34 override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 35 36 if indexPath.section == 3 { 37 switch indexPath.row { 38 case 0: // 開発者の他のアプリを見る 39 appStoreDialog() 40 break 41 case 1: // Twitterで問い合わせ 42 t?.fuguaiHoukokuForTwitter() 43 break 44 case 2: // メールで問い合わせ 45 t?.fuguaiHoukokuForMail() 46 break 47 default: break 48 49 } 50 } 51 tableView.deselectRow(at: indexPath, animated: true) 52 } 53 54 55}

呼び出される側

Swift

1import Foundation 2import MessageUI // メールを送るために必要 3 4public class Toiawase : NSObject , MFMailComposeViewControllerDelegate{ 5 var parent : UIViewController? 6 7 public init(parent: UIViewController) { 8 self.parent = parent 9 } 10 11 12 public func fuguaiHoukokuForMail() { 13 // メールを送信できるかチェック 14 if MFMailComposeViewController.canSendMail()==false { 15 print("Email Send Failed") 16 return 17 } 18 let mailViewController = MFMailComposeViewController() 19 let toRecipients = ["hogehoge@gmail.com"] //Toのアドレス指定 20 21 mailViewController.mailComposeDelegate = self 22 mailViewController.setSubject("不具合報告/機能追加要望") 23 mailViewController.setToRecipients(toRecipients) //Toアドレスの表示 24 self.parent?.present(mailViewController, animated: true, completion: nil) 25 26 } 27 28 29 // 呼ばれない! 30 public func mailComposeController(controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) { 31 switch result { 32 case .cancelled: 33 print("キャンセル") 34 break 35 case .saved: 36 print("下書き保存") 37 break 38 case .sent: 39 print("送信成功") 40 break 41 default: 42 print("送信失敗") 43 } 44 controller.dismiss(animated: true, completion: nil) 45 } 46 47}

delegateが呼ばれないことのデバッグのやり方として何か有益なやり方はないでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

didFinishWith メソッドの第一引数 controller の前に _ が必要です。

swift

1 func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {

メソッド名を間違えないための有益なやり方は、メソッド名を入力するときに Xcode のコード補完機能を有効に使って、とりあえず mail と打って候補が現れるのを待つことです。


この _ の呼び名ですが、外部引数名の省略、でしょうか。探しても古い記事しか見当たらなかったので、解説を書きます。

まず、Swift の関数やメソッドを呼び出すときは、引数名が必要です。

swift

1func add(x: Int, y: Int) -> Int { 2 return x + y 3} 4print(add(x: 1, y: 2))

この引数名ですが、外部名と内部名に分けて書くことができます。
次の関数では、x と y は外部引数名、a と b は内部引数名になります。

swift

1func add(x a: Int, y b: Int) -> Int { 2 return a + b 3} 4print(add(x: 1, y: 2))

さらに、外部引数名を _ とすることで、呼び出し時に省略できるようになります。

swift

1func add(_ a: Int, _ b: Int) -> Int { 2 return a + b 3} 4print(add(1, 2))

というわけで、次のコードでは第一引数 controller の外部引数名を省略する、という意味になります。

swift

1 func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {

以上は現在(Swift 3 以降)の仕様ですが、Swift 1, 2 の頃は、メソッドの第一引数はデフォルトで省略されるという特例がありました。つまり、

swift

1 func mailComposeController(controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {

のように controller の前に _ がなくても controller: は省略されていたのですが、これは美しくないとして Swift 3 の時に仕様変更がありました。(おかげで Sift 2 → 3 の修正は面倒だった…。)

投稿2020/03/16 00:11

編集2020/03/19 03:38
hoshi-takanori

総合スコア7895

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sacakoro

2020/03/19 03:10

ありがとうございます。解決いたしました。この_は文法的にはなんと呼ぶアイテムなのかご教示いただけますか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問