#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
выполнил задание!