Swift email composer not working [duplicate] - ios

I tried 2 codes from different sites to send an email from my iOS app.
When I press the Send button it calls the method mailComposeController and always returns me the log "Mail sent" as the result parameter is always MFMailComposeResultSent.value, even when I have my iPhone 5S in airplane mode.
Besides this, even when I have internet connection, I never receive the email. Already checked SPAM and other folders and waited one entire day if it was delayed but never received even trying several times.
I program with Swift and use XCode 6.4 in a Macbook Pro retina from mid-2014 with Yosemite 10.10.5.
Here the Swift code:
import UIKit
import MessageUI
class ViewController: UIViewController, MFMailComposeViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
if (MFMailComposeViewController.canSendMail()) {
var emailTitle = "Vea Software Feedback"
var messageBody = "Vea Software! :)"
var toRecipents = ["oscar.muntal#gmail.com"]
var mc: MFMailComposeViewController = MFMailComposeViewController()
mc.mailComposeDelegate = self
mc.setSubject(emailTitle)
mc.setMessageBody(messageBody, isHTML: false)
mc.setToRecipients(toRecipents)
self.presentViewController(mc, animated: true, completion: nil)
}else {
println("No email account found")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// Email Delegate
func mailComposeController(controller:MFMailComposeViewController, didFinishWithResult result:MFMailComposeResult, error:NSError) {
switch result.value {
case MFMailComposeResultCancelled.value:
println("Mail cancelled")
case MFMailComposeResultSaved.value:
println("Mail saved")
case MFMailComposeResultSent.value:
println("Mail sent")
case MFMailComposeResultFailed.value:
println("Mail sent failure: \(error.localizedDescription)")
default:
break
}
self.dismissViewControllerAnimated(false, completion: nil)
}
}
Thank you very much for your help in advance.

for me the following code works perfectly fine:
import UIKit
import MessageUI
class ViewController: UIViewController, MFMailComposeViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
if MFMailComposeViewController.canSendMail() {
let toRecipents = ["oscar.muntal#gmail.com"]
let emailTitle = "Vea Software Feedback"
let messageBody = "Vea Software! :)"
let mc: MFMailComposeViewController = MFMailComposeViewController()
mc.mailComposeDelegate = self
mc.setToRecipients(toRecipents)
mc.setSubject(emailTitle)
mc.setMessageBody(messageBody, isHTML: false)
presentViewController(mc, animated: true, completion: nil)
} else {
print("cannot send mails")
}
}
func mailComposeController(controller: MFMailComposeViewController, didFinishWithResult result: MFMailComposeResult, error: NSError?) {
switch result {
case MFMailComposeResultCancelled:
print("Mail cancelled")
case MFMailComposeResultSaved:
print("Mail saved")
case MFMailComposeResultSent:
print("Mail sent")
case MFMailComposeResultFailed:
print("Mail sent failure: \(error?.localizedDescription)")
default:
break
}
dismissViewControllerAnimated(true, completion: nil)
}
}

Thanks to Andre Slotta I solved my problem.
The problem was that I didn't have enabled the "Mail" Switch in the Settings > Mail, Contacts, Calendar > myemailaccount.
This enables to send and receive emails from the native iOS app. Instead of this I just had this enabled for the "Contacts", "Calendars" and "Notes", and use the Gmail iOS app for the Email purposes in my iPhone.
It worked with my initial code also, so it wasn't a code problem at all and everyone can try my initial code in Swift (not Swift2).
Thanks again Andre Slotta for your help!!!

Please add you email account in your mobile phone Setting!

Related

Go back to previous app(Swift ios)

My application can open PDF-files. So I registered it for PDF-files. When I open a PDF-file from the mail-app my application get called and the following function is called:
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
let rect = app.keyWindow?.rootViewController?.view.bounds
viewController.view.backgroundColor = UIColor.red
let picker = UIPickerView(frame: CGRect(x: 0, y: 100, width: (rect?.width)!, height: (rect?.height)! / 3))
picker.delegate = self
picker.dataSource = self
viewController.view.addSubview(picker)
let okButton = UIButton(frame: CGRect(x: 0, y: 100 + ((rect?.height)! / 3), width: ((rect?.width)! / 2) - 20, height: 30))
okButton.setTitle("Ok", for: .normal)
okButton.addTarget(self, action: #selector(AppDelegate.endApp), for: .touchUpInside)
viewController.view.addSubview(okButton)
app.keyWindow?.rootViewController?.present(viewController, animated: true, completion: nil)
return true
}
This works! If the user click on the ok Button I want to go back to the mail-app. How can I do this? I read, that apple don't allow you to switch between apps. But whatsApp is doing this.
I tried it with removing the viewController:
viewController.view.removeFromSuperview()
But then I only get a black screen.
The only way to launch other applications is by using their URL schemes, the only way to open mail is by using the mailto: scheme, which will always open the compose view.
let email = "foo#bar.com"
let url = URL(string: "mailto:\(email)")
UIApplication.sharedApplication().openURL(url)
Edit: this answer might help you
This will not help you to go back to mail app viewController.view.removeFromSuperview()
It will just remove views from your viewcontroler and black color window is showing.
There is no way to get back to mail-app even if you use openURL.
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"mailto:"]];
This will open email composer, but practically you will not be able to get back to mail app.
Swift
let url = URL(string: "mailto:\abc#xyz.com")
UIApplication.sharedApplication().openURL(url)
This will open email composer with sender as abc#xyz.com.
If you want to attach file and send it through email composer, then make like below code.
import UIKit
import MessageUI
class ViewController: UIViewController, MFMailComposeViewControllerDelegate {
#IBAction func launchEmail(sender: AnyObject) {
var emailTitle = "EmailTitle"
var messageBody = "Email BodyFeature request or bug report?"
var toRecipents = ["abc#xyz.com"]
var mc: MFMailComposeViewController = MFMailComposeViewController()
mc.mailComposeDelegate = self
mc.setSubject(emailTitle)
mc.setMessageBody(messageBody, isHTML: false)
mc.setToRecipients(toRecipents)
self.presentViewController(mc, animated: true, completion: nil)
}
func mailComposeController(controller:MFMailComposeViewController, didFinishWithResult result:MFMailComposeResult, error:NSError) {
switch result {
case MFMailComposeResultCancelled:
print("Mail cancelled")
case MFMailComposeResultSaved:
print("Mail saved")
case MFMailComposeResultSent:
print("Mail sent")
case MFMailComposeResultFailed:
print("Mail sent failure: \(error?.localizedDescription)")
default:
break
}
self.dismissViewControllerAnimated(true, completion: nil)
}
}
I made it with the following code:
viewController.dismiss(animated: false, completion: nil)
let mailURL = NSURL(string: "message://")!
if UIApplication.shared.canOpenURL(mailURL as URL) {
UIApplication.shared.openURL(mailURL as URL)
}
Thats good enough for me.
thank you #Jeremy your link helped me!

Application tried to present a nil modal view controller on target when sending text

I'm trying to sent a text message and have controller set up like so, but I get an error message 'NSInvalidArgumentException', reason: 'Application tried to present a nil modal view controller on target <Ally.TextMessageController: 0x7fd5361278e0>.' I've made sure that in my storyboard I'm connecting it to TextMessageController so I'm not quite sure what is causing the crash.
class TextMessageController: UIViewController, MFMessageComposeViewControllerDelegate {
var phone: String?
override func viewDidLoad() {
super.viewDidLoad()
print(phone)
var messageVC = MFMessageComposeViewController()
messageVC.body = "Hey I need help, are you available";
messageVC.recipients = ["555555555"]
messageVC.messageComposeDelegate = self;
presentViewController(messageVC, animated: false, completion: nil)
// Do any additional setup after loading the view.
}
func canSendText() -> Bool {
return MFMessageComposeViewController.canSendText()
}
func messageComposeViewController(controller: MFMessageComposeViewController!, didFinishWithResult result: MessageComposeResult) {
self.dismissViewControllerAnimated(true, completion: nil)
switch (result.rawValue) {
case MessageComposeResultCancelled.rawValue:
print("Message was cancelled")
self.dismissViewControllerAnimated(true, completion: nil)
case MessageComposeResultFailed.rawValue:
print("Message failed")
self.dismissViewControllerAnimated(true, completion: nil)
case MessageComposeResultSent.rawValue:
print("Message was sent")
self.dismissViewControllerAnimated(true, completion: nil)
default:
break;
}
}
Here is the error message
'NSInvalidArgumentException', reason: 'Application tried to present a nil modal view controller on target <Ally.TextMessageController: 0x7fd5361278e0>.'
You should first check whether device can send the text message and then only present it. For instance simulator can not send text message thus your code will crash in it. Along with simulator, user’s device may not be set up for the delivery of messages. So perform following check
if messageVC.canSendText() {
presentViewController(messageVC, animated: false, completion: nil)
}

MFMailComposeViewController appears for a second then disappears

I have done the usual set up of the MFMailComposeViewController() as per Swift Guide
https://developer.apple.com/library/prerelease/ios/documentation/MessageUI/Reference/MFMailComposeViewController_class/
but when I run this then the email appears for a split second, disappears and I get the error message "MailCompositionService quit unexpectedly".
here is the full code
import Foundation
import UIKit
import MessageUI
class ViewController: UIViewController, MFMailComposeViewControllerDelegate {
#IBAction func showEmail(sender: AnyObject) {
let composeVC = MFMailComposeViewController()
composeVC.mailComposeDelegate = self
// Configure the fields of the interface.
composeVC.setToRecipients(["address#example.com"])
composeVC.setSubject("Hello!")
composeVC.setMessageBody("Hello from California!", isHTML: false)
// Present the view controller modally.
self.presentViewController(composeVC, animated: true, completion: nil)
}
func mailComposeController(controller: MFMailComposeViewController,
didFinishWithResult result: MFMailComposeResult, error: NSError?) {
switch result.rawValue {
case MFMailComposeResultCancelled.rawValue:
print("Mail cancelled")
case MFMailComposeResultSaved.rawValue:
print("Mail saved")
case MFMailComposeResultSent.rawValue:
print("Mail sent")
case MFMailComposeResultFailed.rawValue:
print("Mail sent failure: \(error!.localizedDescription)")
default:
break
}
controller.dismissViewControllerAnimated(true, completion: nil)
}}
This is a known bug in the xcode simulator. It should work fine on your device.
Your code is correct. The MFMailComposeViewController component can't be tested in the iOS simulator only in the device.
If you look this Thread in Apple Developer Forums the problem has a ticket in Apple Bug Report but still without any fix.

Tried to send email from in-app and doesn't work - Swift (iOS)

I tried 2 codes from different sites to send an email from my iOS app.
When I press the Send button it calls the method mailComposeController and always returns me the log "Mail sent" as the result parameter is always MFMailComposeResultSent.value, even when I have my iPhone 5S in airplane mode.
Besides this, even when I have internet connection, I never receive the email. Already checked SPAM and other folders and waited one entire day if it was delayed but never received even trying several times.
I program with Swift and use XCode 6.4 in a Macbook Pro retina from mid-2014 with Yosemite 10.10.5.
Here the Swift code:
import UIKit
import MessageUI
class ViewController: UIViewController, MFMailComposeViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
if (MFMailComposeViewController.canSendMail()) {
var emailTitle = "Vea Software Feedback"
var messageBody = "Vea Software! :)"
var toRecipents = ["oscar.muntal#gmail.com"]
var mc: MFMailComposeViewController = MFMailComposeViewController()
mc.mailComposeDelegate = self
mc.setSubject(emailTitle)
mc.setMessageBody(messageBody, isHTML: false)
mc.setToRecipients(toRecipents)
self.presentViewController(mc, animated: true, completion: nil)
}else {
println("No email account found")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// Email Delegate
func mailComposeController(controller:MFMailComposeViewController, didFinishWithResult result:MFMailComposeResult, error:NSError) {
switch result.value {
case MFMailComposeResultCancelled.value:
println("Mail cancelled")
case MFMailComposeResultSaved.value:
println("Mail saved")
case MFMailComposeResultSent.value:
println("Mail sent")
case MFMailComposeResultFailed.value:
println("Mail sent failure: \(error.localizedDescription)")
default:
break
}
self.dismissViewControllerAnimated(false, completion: nil)
}
}
Thank you very much for your help in advance.
for me the following code works perfectly fine:
import UIKit
import MessageUI
class ViewController: UIViewController, MFMailComposeViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
if MFMailComposeViewController.canSendMail() {
let toRecipents = ["oscar.muntal#gmail.com"]
let emailTitle = "Vea Software Feedback"
let messageBody = "Vea Software! :)"
let mc: MFMailComposeViewController = MFMailComposeViewController()
mc.mailComposeDelegate = self
mc.setToRecipients(toRecipents)
mc.setSubject(emailTitle)
mc.setMessageBody(messageBody, isHTML: false)
presentViewController(mc, animated: true, completion: nil)
} else {
print("cannot send mails")
}
}
func mailComposeController(controller: MFMailComposeViewController, didFinishWithResult result: MFMailComposeResult, error: NSError?) {
switch result {
case MFMailComposeResultCancelled:
print("Mail cancelled")
case MFMailComposeResultSaved:
print("Mail saved")
case MFMailComposeResultSent:
print("Mail sent")
case MFMailComposeResultFailed:
print("Mail sent failure: \(error?.localizedDescription)")
default:
break
}
dismissViewControllerAnimated(true, completion: nil)
}
}
Thanks to Andre Slotta I solved my problem.
The problem was that I didn't have enabled the "Mail" Switch in the Settings > Mail, Contacts, Calendar > myemailaccount.
This enables to send and receive emails from the native iOS app. Instead of this I just had this enabled for the "Contacts", "Calendars" and "Notes", and use the Gmail iOS app for the Email purposes in my iPhone.
It worked with my initial code also, so it wasn't a code problem at all and everyone can try my initial code in Swift (not Swift2).
Thanks again Andre Slotta for your help!!!
Please add you email account in your mobile phone Setting!

xcode 6 beta 4 - MessageComposeResult is not convertible to OptionalNilComparisonType

I have just upgraded from Xcode 6 Beta 3 to Beta 4. In 3 my app was compiling perfectly however in 4 I have the following error. Can anyone explain and provide a solution please.
func messageComposeViewController(sendMsg: MFMessageComposeViewController, didFinishWithResult result: MessageComposeResult) {
switch result {
case MessageComposeResultSent : //Error: MessageComposeResult is not convertible to _OptionalNilComparisonType
label2.text = "Msg Sent"
case MessageComposeResultCancelled : //Error: MessageComposeResult is not convertible to _OptionalNilComparisonType
label2.text = "Msg Send Cancelled"
case MessageComposeResultFailed : //Error: MessageComposeResult is not convertible to _OptionalNilComparisonType
label2.text = "Msg Send Failed"
default:
label2.text = "Msg Error"
}
self.dismissViewControllerAnimated(true, completion: nil)
self.reloadInputViews()
}
func messageComposeViewController(controller: MFMessageComposeViewController!, didFinishWithResult result: MessageComposeResult) {
switch result.value {
case MessageComposeResultSent.value :
println("enviado")
case MessageComposeResultCancelled.value :
println("cancelado")
case MessageComposeResultFailed.value :
println("fallo")
default:
println("")
}
}
It's a bug in the way this module is bridged to Swift. Report it. To use the module, stay in Objective-C until the Swift bridging bug is fixed.
The main part of the bug as it stands seems to me to be:
This should be an enum, and it isn't; it's a struct
The struct has a value, which ought to be capable of comparison, but it has no getter (you can set it on initialization but you can't get it later)
For Swift 2, you will need to use rawValue:
// MARK: MFMessageComposeViewControllerDelegate
func messageComposeViewController(controller:MFMessageComposeViewController, didFinishWithResult result:MessageComposeResult) {
controller.dismissViewControllerAnimated(true, completion:nil)
switch result.rawValue {
case MessageComposeResultSent.rawValue:
print("cancelado")
case MessageComposeResultCancelled.rawValue :
print("canceled...")
case MessageComposeResultFailed.rawValue :
print("fail...")
default:
print("default...")
}
}
Of course, if you're just interested in one particular value, you could use an if statement as such:
if (result.rawValue == MessageComposeResultCancelled.rawValue) {
// Message canceled.
}
For Swift 3.0, you will need this:
func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult){
switch result.rawValue {
case MessageComposeResult.sent.rawValue:
print("sent")
break
case MessageComposeResult.cancelled.rawValue:
print("cancelled")
break
case MessageComposeResult.failed.rawValue:
print("failed")
break
default:
break
}
self.dismiss(animated: true) { () -> Void in
}
}
#IBAction func sentSMSAction(_ sender: AnyObject) {
if MFMessageComposeViewController.canSendText() {
let messageVC = MFMessageComposeViewController()
messageVC.body = "My first custom SMS";
messageVC.recipients = ["0123456789"]
messageVC.messageComposeDelegate = self;
self.present(messageVC, animated: false, completion: nil)
}
}

Resources