0

There are dozens of Stackoverflow answers for mailto links in Swift 5.

The consensus look like this

let url = NSURL(string: "mailto:jon.doe@mail.com")
UIApplication.sharedApplication().openURL(url)

But how do I actually use this code? Ideally in an alert, but at least a general Text element

import SwiftUI

struct MainMenu: View {
    @State private var showAlert = false
    
    // What do I put here
    var emailLink:UIApplication {
        let url = URL(string: "mailto:jon.doe@mail.com")!
        return UIApplication.shared.openURL(url)
    }
    
    // To make it work in here
    var body: some View {
        HStack(alignment: .center, spacing: .zero, content: {
            Text(
                "Here is an email link \(emailLink)"
            )
            
            Button(action: {
                showAlert = true
            }) {
                Text("MENU")
            }
            .alert(isPresented: $showAlert, content: {
                Alert(
                    title: Text("Title Here"),
                    message: Text(
                        "Need Help, \(emailLink)"
                    )
                )
            })
        })
    }
}

lando2319
  • 1,509
  • 1
  • 19
  • 27

2 Answers2

3

Without an Alert, based on the suggestive comment of George this works:

var body: some View {
    Text(
        "Here is an email link "
    )
            
    Link("jon.doe@mail.com", destination: URL(string: "mailto:jon.doe@mail.com")!)
lando2319
  • 1,509
  • 1
  • 19
  • 27
  • you commented saying you preferred it in an alert " Ideally in an alert". – cole Apr 30 '22 at 02:14
  • post an answer that works with alert and I'll mark it – lando2319 Apr 30 '22 at 02:15
  • it does work with alert, it uses a Button to openURL for mailto when you select the email button in the alert. Mailto doesn't work in the simulator, hence no mail app. I'm using something similar in my application for email support. – cole Apr 30 '22 at 02:17
  • Im unable to post a screenshot as a comment, the code you posted results in a view error `Cannot convert value of type 'String' to expected argument type '() -> Alert'` – lando2319 Apr 30 '22 at 02:22
  • compiles just fine, I just copied and pasted the exact code from the site back to a new project. What's the error then? Please update your answer with the updated code you are using. – cole Apr 30 '22 at 02:23
  • can you update your question with the code you are now using. – cole Apr 30 '22 at 02:27
  • I don't doubt that it's working for you, unfortunately It's not compiling for me and therefore I cannot mark it as working for me. https://imgur.com/a/Nf44maK – lando2319 Apr 30 '22 at 02:29
  • which version of Xcode are you using? – cole Apr 30 '22 at 02:36
0

You can use Environment var openURL for this, documentation here.

struct ContentView: View {
    @Environment(\.openURL) var openURL
    @State var alert: Bool = false
    var body: some View {
        HStack {
            Button(action: {
                alert.toggle()
            }, label: {
                Label("Email", systemImage: "envelope.fill")
            })
        }
        .alert("Contact", isPresented: $alert, actions: {
            Button(action: {
                mailto("jon.doe@mail.com")
            }, label: {
                Label("Email", systemImage: "envelope.fill")
            })
            Button("Cancel", role: .cancel, action: {})
        })
    }
    
    func mailto(_ email: String) {
        let mailto = "mailto:\(email)".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
        print(mailto ?? "")
        if let url = URL(string: mailto!) {
            openURL(url)
        }
    }
}

alert

cole
  • 1,039
  • 1
  • 8
  • 35
  • Thanks for the suggestion, I was unable to get the above code to work, after removing the hstack which was mistakely getting the alert, instead of the button, I was still getting errors about the alert conforming to Text. – lando2319 Apr 30 '22 at 02:13
  • Thank for the suggestion, I'm getting `Cannot convert value of type 'String' to expected argument type '() -> Alert'` with the above code – lando2319 Apr 30 '22 at 02:23