I've just added an email capability to my app, so that the user can send me an email containing the app's log files and current defaults. This all works great UNTIL it's time to send the email and dismiss the MFMailComposeViewController, at which point my app freezes.
I use a button in a table cell to invoke the MFMailComposeViewController. Hitting the button calls my sendEmail function:
(Note that "logSB" resembles the print command but logs to a file using SwiftyBeaver logging.)
func sendEmail() {
if MFMailComposeViewController.canSendMail() {
let mail = MFMailComposeViewController()
mail.mailComposeDelegate = self
mail.setToRecipients(["support@aircompare.us"])
mail.setSubject("AirCompare user report")
mail.setMessageBody("<p>Thanks for helping to improve AirCompare. Your app logs and settings files are attached. Please include any details describing any problems you are having.</p>", isHTML: true)
let filemgr = FileManager.default
let dir: URL = filemgr.urls(for: .documentDirectory, in: .userDomainMask).last! as URL
let files = ["swiftybeaver.log","swiftybeaverX.log", "defaultsFile.txt"]
for file in files {
let url = dir.appendingPathComponent(file)
if filemgr.fileExists(atPath: url.path) {
self.logSB.verbose("Found the \(file) file")
if let fileData = NSData(contentsOfFile: url.path)
{
logSB.debug("Attachment File data loaded for \(file)")
mail.addAttachmentData(fileData as Data, mimeType: "text/plain", fileName: file)
}
} else {
self.logSB.warning("\(file) file not found at \(url.absoluteString)")
}
}
present(mail, animated: true)
} else {
/
logSB.error("App cannot send email")
}
}
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
logSB.debug("Mail composer succeeded with result \(String(describing: result))")
if error != nil {
logSB.error("Mail composer returned error \(String(describing: error))")
}
controller.dismiss(animated: true)
}
As I said, this is all working great and the MFMailComposeResult comes back without an error. But when the email controller is dismissed (line 38), the app freezes upon trying to redraw the table, I guess. And BTW, the email is not sent.
I know how I could probably "cheat" and navigate back to some view, but why doesn't dismiss work?
Debugger points me to:
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return ACsections[section] // ACsections contains the names of each table section
}
...and says the index is out of range.