i have table of contacts , the logic user will multi select contacts to send them sms invite to the app , my issue is after popup sms compose( when close or send ) the composer is closed and the app is been restarted, is it how its work? why it should reset the app i am just closing or canceling the sms compose controller !
here is what i did
//Send SMS
func sendSMS( to : [String] = [] , message : String = "" )
{
if (MFMessageComposeViewController.canSendText())
{
let controller = MFMessageComposeViewController()
controller.body = message
controller.recipients = to
if let topController = UIApplication.topViewController()
{
controller.messageComposeDelegate = topController as MFMessageComposeViewControllerDelegate
topController.present(controller, animated: true, completion: nil)
}
}
}
extension UIViewController: MFMessageComposeViewControllerDelegate {
public func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) {
switch (result.rawValue) {
case MessageComposeResult.cancelled.rawValue:
print("Message was cancelled")
controller.dismiss(animated: true, completion: nil)
case MessageComposeResult.failed.rawValue:
print("Message failed")
controller.dismiss(animated: true, completion: nil)
case MessageComposeResult.sent.rawValue:
print("Message was sent")
controller.dismiss(animated: true, completion: nil)
default:
break;
}
}
}
is there anyway to close sms composer without reloading the app ?
Related
Using the code below found on another stack overflow page I keep getting this error when a button is pressed to form an email within my app I am currently working on. Can someone help?
error: [PPT] Error creating the CFMessagePort needed to communicate with PPT.
import Foundation
import MessageUI
class EmailHelper: NSObject, MFMailComposeViewControllerDelegate {
public static let shared = EmailHelper()
private override init() {
//
}
func sendEmail(subject:String, body:String, to:String){
if !MFMailComposeViewController.canSendMail() {
// Utilities.showErrorBanner(title: "No mail account found", subtitle: "Please setup a mail account")
return //EXIT
}
let picker = MFMailComposeViewController()
picker.setSubject(subject)
picker.setMessageBody(body, isHTML: true)
picker.setToRecipients([to])
picker.mailComposeDelegate = self
EmailHelper.getRootViewController()?.present(picker, animated: true, completion: nil)
}
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
EmailHelper.getRootViewController()?.dismiss(animated: true, completion: nil)
}
static func getRootViewController() -> UIViewController? {
(UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate)?.window?.rootViewController
// OR If you use SwiftUI 2.0 based WindowGroup try this one
// UIApplication.shared.windows.first?.rootViewController
}
}
Button(action: {
EmailHelper.shared.sendEmail(subject: "Anything...", body: "", to: "")
}) {
Text("Send Email")
}
I have an app which allows me to send E-Mails. I already got it as far, as that the Mail Controller is closed after type on the send or cancel button. But I would like to have an ''Popup'' or something inside of the app which tell the user whether they have send the mail or cancelled it.
The commented out code had been my try let the app say it, but it wouldn't work because of some warnings.
#IBAction func Senden(_ sender: Any) {
let toRecipients = ["Mail#adress.com"]
let mc: MFMailComposeViewController = MFMailComposeViewController()
mc.mailComposeDelegate = self
mc.setToRecipients(toRecipients)
mc.setSubject(FirmaFeld.text!)
mc.setMessageBody("Firma: \(FirmaFeld.text!) \n\n Kontaktperson: \(KontaktpersonFeld.text!) \n\n EMail: \(EMailFeld.text!) \n\n Anliegen: \(NachrichtFeld.text!)", isHTML: false)
self.present(mc, animated: true, completion: nil)
}
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Swift.Error?) {
controller.dismiss(animated: true, completion: nil)
}
/* switch result.rawValue {
case MFMailComposeResult.cancelled.rawValue:
print("Mail cancelled")
case MFMailComposeResult.saved.rawValue:
print("Mail saved")
case MFMailComposeResult.sent.rawValue:
print("Mail sent")
case MFMailComposeResult.failed.rawValue:
print("Mail sent failure: %#", [error!.localizedDescription])
default:
break
}
// Dismiss the mail compose view controller.
self.dismiss(animated: true, completion: nil)
}*/
#IBAction func dismissKeyboard(_ sender: Any) {
self.resignFirstResponder()
}
Show the alertController inside the completionBlock.
controller.dismiss(animated: true, completion: {
if result == .cancelled {
let alertController = UIAlertController(title: "E-Mail not sent!", message: "E-Mail not sent.", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .cancel, handler: { (action: UIAlertAction!) in
}))
present(alertController, animated: true, completion: nil)
}
})
Same way when mail send.
I'm implementing a mail controller in my app but I can't figure out why it won't close when clicking save draft or delete draft. The window gets stuck on the email screen and I can't click "Cancel" a second time either.
#IBAction func emailButtonTapped(_ sender: UIButton) {
guard MFMailComposeViewController.canSendMail() else {
if !MFMailComposeViewController.canSendMail() {
print("Can not send email")
return
}
return
}
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
dismiss(animated: true, completion: nil)
}
let mailComposer = MFMailComposeViewController()
mailComposer.mailComposeDelegate = self
mailComposer.setToRecipients(["example#example.com"])
mailComposer.setSubject("Look at this")
mailComposer.setMessageBody("Hello, this is an email from the app I made.", isHTML: false)
present(mailComposer, animated: true, completion: nil)
}
I successfully fixed the issue, and it was a pretty stupid one!
Some code was outside the emailButtonTapped func:
#IBAction func emailButtonTapped(_ sender: UIButton) {
//guard MFMailComposeViewController.canSendMail() else {
if !MFMailComposeViewController.canSendMail() {
print("Can not send email")
return
}
let mailComposer = MFMailComposeViewController()
mailComposer.mailComposeDelegate = self
mailComposer.setToRecipients(["example#example.com"])
mailComposer.setSubject("Look at this")
mailComposer.setMessageBody("Hello, this is an email from the app I made.", isHTML: false)
present(mailComposer, animated: true, completion: nil)
}
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
dismiss(animated: true, completion: nil)
}
Swift 4
// MARK: - SEND EMAIL BUTTON
#IBAction func SendEmailButt(_ sender: AnyObject) {
// This string containes standard HTML tags, you can edit them as you wish
let messageStr = "Hello,"
let mailComposer = MFMailComposeViewController()
mailComposer.mailComposeDelegate = self
mailComposer.setSubject("Title")
mailComposer.setMessageBody(messageStr, isHTML: true)
if MFMailComposeViewController.canSendMail() { present(mailComposer, animated: true, completion: nil)
} else {
print("Your device cannot send emails. Please configure an email address into Settings -> Mail, Contacts, Calendars.")
}
}
// Email delegate
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
var resultMess = ""
switch result.rawValue {
case MFMailComposeResult.cancelled.rawValue:
resultMess = "Mail cancelled"
case MFMailComposeResult.saved.rawValue:
resultMess = "Mail saved"
case MFMailComposeResult.sent.rawValue:
resultMess = "Thanks for contacting us!\nWe'll get back to you asap."
case MFMailComposeResult.failed.rawValue:
resultMess = "Something went wrong with sending Mail, try again later."
default:break
}
// Show email result alert
print(resultMess)
dismiss(animated: true, completion: nil)
}
Can you try this once instead:
func mailComposeController(controller: MFMailComposeViewController, didFinishWithResult result: MFMailComposeResult, error: NSError?) {
// Dismiss the mail compose view controller.
controller.dismissViewControllerAnimated(true, completion: nil)
}
Check the following Code.
#IBAction func sendEmailButtonTapped(sender: AnyObject) {
let mailComposeViewController = configuredMailComposeViewController()
if MFMailComposeViewController.canSendMail() {
self.presentViewController(mailComposeViewController, animated: true, completion: nil)
} else {
self.showSendMailErrorAlert()
}
}
func configuredMailComposeViewController() -> MFMailComposeViewController {
let mailComposerVC = MFMailComposeViewController()
mailComposerVC.mailComposeDelegate = self
mailComposerVC.setToRecipients([])
mailComposerVC.setSubject("Sending In-App Email")
mailComposerVC.setMessageBody("Sending Email through your app in Swift", isHTML: false)
return mailComposerVC
}
func showSendMailErrorAlert() {
let sendMailErrorAlert = UIAlertView(title: "Could Not Send Email", message: "Your device could not send Email. Please check Email configuration and try again.", delegate: self, cancelButtonTitle: "OK")
sendMailErrorAlert.show()
}
// MFMailComposeViewControllerDelegate Method
func mailComposeController(controller: MFMailComposeViewController!, didFinishWithResult result: MFMailComposeResult, error: NSError!) {
controller.dismissViewControllerAnimated(true, completion: nil)
}
I am brand new in iOS developing and xCode.
Previously i developed android and i know i should work with Intent to make call and send SMS in android App.
Now i want to develop a simple App that when i press a Button it send a SMS to a specific number.
So i installed a Mac OS 10.11 VM on my Ubuntu.
And could connect connect my iPhone 5 to that and run my simple Hello World App in real iPhone Device and not simulator.
Now i created a Button in StoryBoard and make a funcion by following this article :
Send SMS Message Toturial
Also look at other links and was similar.
Here is my simple ViewController.swift.
import UIKit
import MessageUI
class ViewController: UIViewController, MFMessageComposeViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func sendMessage(sender: AnyObject) {
print("Send button pressed") //display a text to make sure is calling
if MFMessageComposeViewController.canSendText() {
let controller = MFMessageComposeViewController()
controller.body = "TestMessage "
controller.recipients = ["xxxxxxxxx", "xxxxxxxxx"] // sending for two numbers
controller.messageComposeDelegate = self
self.presentViewController(controller, animated: true, completion: nil)
}
}
func messageComposeViewController(controller: MFMessageComposeViewController, didFinishWithResult result: MessageComposeResult) {
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;
}
}
}
And also created a Simple Button and link that to sendMessage above.
When i run the app, displays the button and when i press it, it seems it is doing something, but the SMS is not sent.
Any Idea??
I really appreciate it.
Update : As our friend said i added print("Send button pressed") in sendMessage Button, so i find out the button call sendMessage when i press it.
I finally did it, I mixed up two solutions,
First of all,i changed the function of sendMessage and renamed it to sendText, in this way :
#IBAction func sendText(sender: AnyObject) {
if (MFMessageComposeViewController.canSendText()) {
let controller = MFMessageComposeViewController()
controller.body = "Text Body"
controller.recipients = ["xxxxxxxxxxx"]
controller.messageComposeDelegate = self
self.presentViewController(controller, animated: true, completion: nil)
}
}
And the protocol of MessageComposeViewController is :
func messageComposeViewController(controller: MFMessageComposeViewController, didFinishWithResult result: MessageComposeResult) {
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;
}
}
And then click on the button in storyboards, and press control key and drag the button to ViewController and select the sendText function, now it works correctly.
Thx to my Friend #Kabiroberai for help and give some time.
Heres the bottom function converted to swift 4:
func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) {
switch (result.rawValue) {
case MessageComposeResult.cancelled.rawValue:
print("Message was cancelled")
self.dismiss(animated: true, completion: nil)
case MessageComposeResult.failed.rawValue:
print("Message failed")
self.dismiss(animated: true, completion: nil)
case MessageComposeResult.sent.rawValue:
print("Message was sent")
self.dismiss(animated: true, completion: nil)
default:
break;
}
}
I am trying to add a send email button to a Sprite Kit game. I can get the email dialog to show up. But if I hit cancel, the app will crash or do nothing. If I hit send, the email will send, but the dialog stays. I cannot get the mailComposeController function to fire...please help!
Code:
import Foundation
import UIKit
import MessageUI
class MailViewController: UIViewController, MFMailComposeViewControllerDelegate {
let systemVersion = UIDevice.currentDevice().systemVersion
let devicemodel = UIDevice.currentDevice().model
let appVersion = NSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"] as! String
let appBuild = NSBundle.mainBundle().infoDictionary?["CFBundleVersion"] as! String
let myrootview2 = UIApplication.sharedApplication().keyWindow?.rootViewController
let mailComposerVC = MFMailComposeViewController()
override func viewDidLoad() {
super.viewDidLoad()
}
func sendEmailButtonTapped(sender: AnyObject) {
let mailComposeViewController = configuredMailComposeViewController()
if MFMailComposeViewController.canSendMail() {
self.view.window?.rootViewController = mailComposerVC
print("This is the rootview2: \(myrootview2)")
myrootview2!.presentViewController(mailComposeViewController, animated: true, completion: nil)
} else {
self.showSendMailErrorAlert()
}
}
func configuredMailComposeViewController() -> MFMailComposeViewController {
var msgbody: String
mailComposerVC.mailComposeDelegate = self
msgbody = "\n\nDevice: \(devicemodel)\niOS Version: \(systemVersion)\nApp Version: \(appVersion)\nApp Build Number: \(appBuild)\n"
mailComposerVC.setToRecipients(["test1#test.com"])
mailComposerVC.setSubject("test subject")
mailComposerVC.setMessageBody(msgbody, isHTML: false)
//print(mailComposerVC)
return mailComposerVC
}
func showSendMailErrorAlert() {
let sendMailErrorAlert = UIAlertView(title: "Could Not Send Email", message: "Your device could not send e-mail. Please check e-mail configuration and try again.", delegate: self, cancelButtonTitle: "OK")
sendMailErrorAlert.show()
}
// THIS DOESN'T GET CALLED WHEN SENDING OR CANCELLING EMAIL!
func mailComposeController(controller: MFMailComposeViewController, didFinishWithResult result: MFMailComposeResult, error: NSError?) {
let test1 = result.rawValue
print(test1)
print(controller)
print(self)
print(myrootview2)
}
The issue is you are making the mailVC as the root view, you have to present it on your view like given below
#IBAction func sendEmailButtonTapped(sender: AnyObject) {
let mailComposeViewController = configuredMailComposeViewController()
if MFMailComposeViewController.canSendMail() {
self.presentViewController(mailComposeViewController, animated: true, completion: nil)
} else {
self.showSendMailErrorAlert()
}
}
func mailComposeController(controller: MFMailComposeViewController!, didFinishWithResult result: MFMailComposeResult, error: NSError!) {
controller.dismissViewControllerAnimated(true, completion: nil)
}