-1

I have a UIAlertView that is triggered via a UIButton.

The UIAlertView displays two buttons, "Open Email" and "Cancel".

"Cancel" removes the UIAlert from the view. I'm trying to make it so when the user taps "Open Email", their device opens the default email application's compose screen, with an email address already in the "sender" section.

Using Swift 3.

Thanks!

import UIKit
import Kingfisher

class SettingsViewController: UIViewController {

@IBAction func copyrightInfo(_ sender: Any) {


    let alert = UIAlertController(title: "Copyright Info", message: "text", preferredStyle: UIAlertControllerStyle.alert)
    alert.addAction(UIAlertAction(title: "I understand", style: UIAlertActionStyle.default, handler: nil))

    self.present(alert, animated: true, completion: nil)



}


@IBAction func helpfeedbackAlert(_ sender: Any) {

    let alertController = UIAlertController(title: "Help & Feedback", message: "text", preferredStyle: .alert)

    let cancel = UIAlertAction(title: "Cancel", style: .destructive, handler: nil)

    let openEmail = UIAlertAction(title: "Open Email", style: .default, handler: nil)


    alertController.addAction(openEmail)
    alertController.addAction(cancel)


    self.present(alertController, animated: true, completion: nil)


}



@IBAction func clearCache(_ sender: Any) {


    //        SDImageCache.shared().clearMemory()
    //        SDImageCache.shared().clearDisk()

    // Clear memory cache right away.
    ImageCache.default.clearMemoryCache()

    // Clear disk cache. This is an async operation.
    ImageCache.default.clearDiskCache()


}

@IBAction func rateApp(_ sender: Any) {

    if let url = URL(string: "https://www.google.com") {
        if #available(iOS 10.0, *) {
            UIApplication.shared.open(url, options: [:]) {
                boolean in
                // do something with the boolean
            }
        } else {
            // Fallback on earlier versions
        }
    }

}

@IBAction func purchasePhotos(_ sender: Any) {

    if let url = URL(string: "https://google.com") {
        if #available(iOS 10.0, *) {
            UIApplication.shared.open(url, options: [:]) {
                boolean in
                // do something with the boolean
            }
        } else {
            // Fallback on earlier versions
        }
    }



}

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.


}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

override var prefersStatusBarHidden: Bool {
    get {
        return true
    }
}


/*
// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?) {
    // Get the new view controller using segue.destinationViewController.
    // Pass the selected object to the new view controller.
}
*/

}
Miles
  • 625
  • 2
  • 9
  • 18

3 Answers3

2

You have to use MFMailComposer to send email, this is how you use it

if MFMailComposeViewController.canSendMail() {
        let mail = MFMailComposeViewController()
        mail.mailComposeDelegate = self
        mail.setToRecipients(["rajatpagare@hotmail.com"])
        mail.setMessageBody("you email body", isHTML: false)
        present(mail, animated: true)
    } else {
        // email is not added in app
    }

Also import MessageUI framework and conform to MFMailComposeViewControllerDelegate

Also you don't need to use openURL like you mentioned in your answer as you are redirecting user from your app to another app, there is no need to do that you can use MFMailComposer.

Rajat
  • 10,977
  • 3
  • 38
  • 55
  • I will try this! Thanks. How do I conform to MFMailComposeViewControllerDelegate? – Miles Nov 27 '16 at 07:44
  • class ViewController: ViewController,MFMailComposeViewControllerDelegate { – Rajat Nov 27 '16 at 07:48
  • Thanks. This works well on a UIButton, but I'm trying to figure out how to attach this to a button within a UIAlertView. (UIAlertAction). – Miles Nov 27 '16 at 07:54
  • You can use it in handler of your UIAlertAction like you have used openURL to send message – Rajat Nov 27 '16 at 07:57
0

I got it working with this code:

    @IBAction func helpfeedbackAlert(_ sender: Any) {

    let alertController = UIAlertController(title: "Help & Feedback", message: "text", preferredStyle: .alert)

    let cancel = UIAlertAction(title: "Cancel", style: .destructive, handler: nil)

    let openEmail = UIAlertAction(title: "Open Email", style: .default, handler: { (actionSheetController) -> Void in let email = "email@example.com"
        let url = NSURL(string: "mailto:\("email@example.com")")
        UIApplication.shared.openURL(url as! URL)})


    alertController.addAction(openEmail)
    alertController.addAction(cancel)


    self.present(alertController, animated: true, completion: nil)



}
Miles
  • 625
  • 2
  • 9
  • 18
  • Looks like you have already found the answer, but if you wanted to extend your functionality to include other email clients than the standard ios mail app, I've written a blog post that details exactly how to do this here: https://medium.com/@harrybloom18/ios-email-picker-99045d940a3d – Harry Bloom Apr 04 '17 at 14:23
  • @beehive-bedlam Thank you very much! – Miles Apr 04 '17 at 20:52
0

First, I assume what do you need to add in your code snippet is only this part:

@IBAction func helpfeedbackAlert(_ sender: Any) {

    let alertController = UIAlertController(title: "Help & Feedback", message: "text", preferredStyle: .alert)

    let cancel = UIAlertAction(title: "Cancel", style: .destructive, handler: nil)

    let openEmail = UIAlertAction(title: "Open Email", style: .default, handler: nil)


    alertController.addAction(openEmail)
    alertController.addAction(cancel)


    self.present(alertController, animated: true, completion: nil)
}

Anyway, what do you need is to fill the handler when you create an instance of the UIAlertAction. Referring to the documentation of the init(title:style:handler:):

handler

A block to execute when the user selects the action. This block has no return value and takes the selected action object as its only parameter.

So, your openEmail should be like:

let openEmail = UIAlertAction(title: "Open Email", style: .destructive, handler: { (actionSheetController) in
            // send your email here...

        })

I'm not pretty sure of the mechanism of how do you want to send an email, but I thik you might want to check MFMailComposeViewController, this question should help you to work with it.

Hope it helped.

Community
  • 1
  • 1
Ahmad F
  • 30,560
  • 17
  • 97
  • 143
  • Thanks a lot! A bit confused on how to add the MFMailCompose code to a handler within a UIAlertAction. It works great when it's attached to a UIButton, but doesn't seem to work when put into the handler on a UIAlertAction. – Miles Nov 27 '16 at 07:55
  • Do the exact same of what are you doing in the button action, but in the closure (same block of where "send your email here..." exist). – Ahmad F Nov 27 '16 at 07:58
  • Works now! Thank you. I did have to add "self." on the "present(mail, animated: true) line. When the email screen opens and I hit "Cancel" or Send the email, the mail view doesn't go away. – Miles Nov 27 '16 at 08:02