I have a button that allows you to send an email with all the content on your app. I'm iterating thru all the data stored in a core data container, and creating a string that I then pass to the sheet presenting the ability to send email.
When I test it, the string always seems to be empty, and I can see an error: [PPT] Error creating the CFMessagePort needed to communicate with PPT.
I'm using the same mechanism I use to email each item on the list, which works like a charm.
Anyway, I've see a lot of posts about the error, but nothing that points to a solution.
Here's the code, maybe it's related to how I call the .sheet
? What am I missing? What's that error even try to tell me?
struct ContentView: View {
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(entity: Jot.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Jot.date, ascending: false)])
var jots: FetchedResults<Jot>
@State private var sheetbackupJotMail = false
//for sending mail
@State var result: Result<MFMailComposeResult, Error>? = nil
@State var isShowingMailView = false
@State private var emailText: String = ""
var body: some View {
NavigationView {
List (jots) { jot in
Text(jot.text!)
}
}
.toolbar {
// toolbar button that send the message with all content
ToolbarItem(placement: .navigation) {
if MFMailComposeViewController.canSendMail() {
Button(action: {
sheetbackupJotMail.toggle()
}) {
Label("Back up all jots", systemImage: "arrow.up.square").foregroundColor(.secondary)
}
// sheet for backing up email
.sheet(isPresented: $sheetbackupJotMail) {
MailView(result: $result) { composer in
emailText = ""
for jot in jots {
emailText = emailText + jot.dateText! + "\n" + jot.text! + "\n\n"
}
print(">>>: " + emailText) //<-- this is always empty, however if I move to the button before the toggle(), I get the right text
// emailing all
composer.setSubject("Jot Backup")
composer.setMessageBody(emailText, isHTML: false)
}
}
}
}
}
}
}
// mail view
import SwiftUI
import UIKit
import MessageUI
public struct MailView: UIViewControllerRepresentable {
@Environment(\.presentationMode) var presentation
@Binding var result: Result<MFMailComposeResult, Error>?
public var configure: ((MFMailComposeViewController) -> Void)?
public class Coordinator: NSObject, MFMailComposeViewControllerDelegate {
@Binding var presentation: PresentationMode
@Binding var result: Result<MFMailComposeResult, Error>?
init(presentation: Binding<PresentationMode>,
result: Binding<Result<MFMailComposeResult, Error>?>) {
_presentation = presentation
_result = result
}
public func mailComposeController(_ controller: MFMailComposeViewController,
didFinishWith result: MFMailComposeResult,
error: Error?) {
defer {
$presentation.wrappedValue.dismiss()
}
guard error == nil else {
self.result = .failure(error!)
return
}
self.result = .success(result)
}
}
public func makeCoordinator() -> Coordinator {
return Coordinator(presentation: presentation,
result: $result)
}
public func makeUIViewController(context: UIViewControllerRepresentableContext<MailView>) -> MFMailComposeViewController {
let vc = MFMailComposeViewController()
vc.mailComposeDelegate = context.coordinator
configure?(vc)
return vc
}
public func updateUIViewController(
_ uiViewController: MFMailComposeViewController,
context: UIViewControllerRepresentableContext<MailView>) {
}
}
Also moving the creation of the text here caused the text I need to mail to be ok, but the error continues to be: PPT] Error creating the CFMessagePort needed to communicate with PPT.
Button(action: {
emailText = ""
for jot in jots {
emailText = emailText + jot.dateText! + "\n" + jot.text! + "\n\n"
}
print(">>>: " + emailText)
sheetbackupJotMail.toggle()
}) {
Label("Back up all jots", systemImage: "arrow.up.square").foregroundColor(.secondary)
}