MFMailComposeViewControllerDelegate не работает Swift 3

#ios #swift #swift3 #mfmailcomposeviewcontroller

#iOS #swift #swift3 #mfmailcomposeviewcontroller

Вопрос:

Я уже некоторое время использую почтовый композитор в нескольких своих приложениях, и с недавнего времени mailComposeDelegate больше не получает вызова.
Я не был уверен, связано ли это с новой версией Swift.
Итак, я подумал, что спрошу и посмотрю, есть ли у кого-нибудь еще подобные проблемы.
Я могу представить почтовый композитор, но он никогда не отклоняется из-за того, что делегат не работает.

Ниже приведена точная копия кода, который я использовал:

 func launchFeedback() {
    guard MFMailComposeViewController.canSendMail() else {
        return
    }

    let emailTitle = "Feedback"
    let messageBody = ""
    let toRecipents = ["johnappleseed@icloud.com"]
    mailComposer.mailComposeDelegate = self
    mailComposer.setSubject(emailTitle)
    mailComposer.setMessageBody(messageBody, isHTML: false)
    mailComposer.setToRecipients(toRecipents)
    self.show(mailComposer, sender: self)
}

func mailComposeController(controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
    print(error)
    controller.dismiss(animated: true, completion: nil)
}
  

Ответ №1:

Это явно ошибка Xcode. Единственным способом обойти это (после поиска, хотя StackOverflow life в течение часа) было следующее:

     @objc(mailComposeController:didFinishWithResult:error:)
    func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult,error: NSError?) {
        controller.dismiss(animated: true)
    }
  

Смотрите макрос @objc перед реализацией метода. Также обратите внимание, что последним параметром должен быть тип NSError вместо Error, как указано в документации Apple (и автоматически заполняется Xcode)

Комментарии:

1. Если это действительно ошибка XCode, она все еще существует в версии 10.3, когда вы вычисляете свои вложения в фоновом потоке и используете другой контроллер представления для выполнения, который отображает контроллер компоновки при увольнении. Но этот ответ все еще решает проблему, поэтому большое одобрение!

Ответ №2:

Swift 3 больше не имеет неназванных первых параметров по умолчанию (см. Это Предложение), поэтому вам нужно добавить символ подчеркивания к вашей функции:

 func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
    print(error)
    controller.dismiss(animated: true, completion: nil)
}
  

Ответ №3:

Swift 4, Xcode 9.1. Моя проблема заключалась в том, что MFMailComposeViewController все работало нормально, но если вы нажмете «Отмена», «Отклонить», а затем попытаетесь открыть его еще раз, кнопки «Отмена» и «Отправить» не будут запускать didFinishWith функцию делегирования. Это происходило потому, что я объявил MFMailComposeViewController как ленивую переменную, и решение состояло в том, чтобы создавать новый экземпляр MFMailComposeViewController каждый раз, когда вы хотите его открыть.

Проблема:

 lazy var mailComposeViewController: MFMailComposeViewController = {
    let mailComposeViewController = MFMailComposeViewController()
    mailComposeViewController.mailComposeDelegate = self
    mailComposeViewController.setToRecipients(["example@test.test"])
    mailComposeViewController.setSubject("subject")
    mailComposeViewController.setMessageBody("test body", isHTML: false)
    return mailComposeViewController
}()
  

Решение:

 func createMailComposeViewController() -> MFMailComposeViewController {
    let mailComposeViewController = MFMailComposeViewController()
    mailComposeViewController.mailComposeDelegate = self
    mailComposeViewController.setToRecipients(["example@test.test"])
    mailComposeViewController.setSubject("subject")
    mailComposeViewController.setMessageBody("test body", isHTML: false)
    return mailComposeViewController
}
  

Комментарии:

1. Это должно было заставить мой мозг взорваться. Теперь, когда я это знаю, это так очевидно! Большое вам спасибо!

Ответ №4:

Потратив 2 хороших часа, я пришел к выводу, что начиная с Xcode 8.3. MFMailComposeViewController не работает на смешанной базе кода swift / objc. Появляются странные ошибки компиляции, которые сначала я подумал, что это из-за моей глупости, но нет.

Это так расстраивает Apple. У большинства из нас, старожилов, есть тонны кода на obj-c, поэтому сценарий чистого swift практически невозможен. Поэтому, когда я переношу классы на swift, мне также приходится иметь дело с дополнительной болью.

Ответ №5:

Добавление

 #import <MessageUI/MessageUI.h> 
  

чтобы AppName-Bridging-Header.h выполнил задание!