Sending SMS from Contacts for Multiple Contacts Fails - ios

Im trying to acheive the same results as: Sending SMS from Contacts Fails
Sending an SMS or "App Invite" to contact(s).
The solution to this problem works, but it only allows you to send an SMS to one person at a time. What I want to do is send an SMS to multiple contacts at one time. Forgive me if this is fairly easy. I've been up for the past 14 hours programming and most things aren't making sense to me right now.
Heres my code:
//MARK : VARIABLES
let contactPickerViewController = CNContactPickerViewController()
let messageViewController = MFMessageComposeViewController()
//MARK : VIEW DID LOAD
override func viewDidLoad() {
super.viewDidLoad()
//-- set delegates equal to self
contactPickerViewController.delegate = self
messageViewController.messageComposeDelegate = self
}
//MARK : MFMESSAGECOMPOSE & CNCONTACTPICKERDELEGATE
func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) {
self.dismiss(animated: true, completion: nil)
}
func contactPicker(_ picker: CNContactPickerViewController, didSelect contacts: [CNContact]) {
//-- select contacts and present message compose view controller
contacts.forEach { (contact) in
for data in contact.phoneNumbers {
let phoneNo = data.value
//-- configure message view controller
messageViewController.recipients = [phoneNo]
messageViewController.body = "Testing Testing"
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.present(self.messageViewController, animated: true, completion: nil)
})
}
}
}
func contactPickerDidCancel(_ picker: CNContactPickerViewController) {
print("cancelled")
}

In your for loop you are attempting to display an MFMessageComposeViewController for each recipient. This won't work as it will attempt to present multiple view controllers concurrently.
You can present a single MFMessageComposeViewController that has all of the recipients specified:
var recipients = [String]()
contacts.forEach { (contact) in
for data in contact.phoneNumbers {
let phoneNo = data.value
recipients.append(phoneNo.stringValue)
}
}
//-- configure message view controller
messageViewController.recipients = recipients
messageViewController.body = "Testing Testing"
self.present(self.messageViewController, animated: true, completion: nil)

Related

How to disable contact section ( message , call , video , mail ) from CNContactPickerViewController

I want to know it possible to remove or disable menu in that section.
Thank you.
extension ViewController: CNContactPickerDelegate {
#IBAction func pickerBtnAction(_ sender: Any) {
let contacVC = CNContactPickerViewController()
contacVC.displayedPropertyKeys = [CNContactPostalAddressesKey]
contacVC.hidesBottomBarWhenPushed = true
contacVC.displayedPropertyKeys = [CNContactGivenNameKey, CNContactImageDataAvailableKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey, CNContactThumbnailImageDataKey, CNContactIdentifierKey];
contacVC.delegate = self
self.present(contacVC, animated: true, completion: nil)
}
func contactPicker(_ picker: CNContactPickerViewController, didSelect contactProperty: CNContactProperty) {
if let phone = contactProperty.value as? CNPhoneNumber {
print(phone.stringValue)
}
}
}
let cncontactVC = CNContactViewController()
cncontactVC.allowsActions = false
You need to use instance property allowsActions of CNContactViewController.
From the official docs,
Determines whether to display buttons for actions such as sending a
text message or initiating a FaceTime call.
while creating an object of CNContactViewController,
let contactVC = CNContactViewController()
contactVC.allowsActions = false
There are other useful properties as well ,
shouldShowLinkedContacts
allowsEditing

How insert image in HTML Body Email Swift 3?

I'm working hard in my app, but I got a problem.
Need insert a image in my HTML code from Swift to send a email.
this is my code, but of course doesn't work!
var h = "<html><body leftmargin=15% topmargin=2% marginwidth=7% marginheight=7%>"
h = h + "<img width=100px src=logoICR.png>"
h = h + "</body></html>"
Please try below code for insert Image inside Email HTML Body.
Code works with Swift 4.0 & Swift 3.1
import MessageUI
class ViewController: UIViewController, MFMailComposeViewControllerDelegate{
override func viewDidLoad() {
super.viewDidLoad()
}
//MARK: - Send Email
#IBAction func actionSendEmail(_ sender: Any) {
if !MFMailComposeViewController.canSendMail() {
print("Mail services are not available")
return
}
let image = UIImage(named:"testImage") // Your Image
let imageData = UIImagePNGRepresentation(image!) ?? nil
let base64String = imageData?.base64EncodedString() ?? "" // Your String Image
let strHtml = "<html><body><p>Header: Hello Test Email</p><p><b><img src='data:image/png;base64,\(String(describing: base64String) )'></b></p></body></html>"
let composeVC = MFMailComposeViewController()
composeVC.mailComposeDelegate = self
// Configure the fields of the interface.
composeVC.setToRecipients(["address#example.com"])
composeVC.setSubject("Hello!")
composeVC.setMessageBody(strHtml, isHTML: true)
// Present the view controller modally.
self.present(composeVC, animated: true, completion: nil)
}
//MARK:- MFMailCompose Delegate Methods
func mailComposeController(_ controller: MFMailComposeViewController,
didFinishWith result: MFMailComposeResult, error: Error?) {
// Dismiss the mail compose view controller.
controller.dismiss(animated: true, completion: nil)
}
}
Give full path of image's: like
<img width=100px src=http://example.com/images/logoICR.png>

Text message function returns error on device

I am retrieving the phone number from my Firebase database, no matter how I enter it into the database it returns an error on my device:
"Message sent to invalid destination. Please check your number and try again. Msg 2127"
The message comes in as an automatic reply immediately after the text is sent out. I have tried entering it into firebase as 111-111-1111 and 1111111111 (not actually using a number 1 but a real phone number).
The calling function works fine however the same number being texted is not working.
var contact: Int!
#IBAction func textButton(_ sender: Any) {
if canSendText() {
if let contactopt = contact{
var messageVC = MFMessageComposeViewController()
messageVC.recipients = ["tel:\(contactopt)"]
messageVC.messageComposeDelegate = self;
self.present(messageVC, animated: false, completion: nil)}}
else {
let errorAlert = UIAlertView(title: "Cannot Send Text Message", message: "Your device is not able to send text messages.", delegate: self, cancelButtonTitle: "OK")
errorAlert.show()
}
}
func canSendText() -> Bool {
return MFMessageComposeViewController.canSendText()
}
func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) {
controller.dismiss(animated: true, completion: nil)
}
#IBAction func callButton(_ sender: UIButton) {
if let contactopt = contact{
if let url = NSURL(string: "tel://\(contactopt)") {
// UIApplication.shared.openURL(url as URL)
UIApplication.shared.open(url as URL, options: [:], completionHandler: nil)
}
}
}
I had to change
messageVC.recipients = ["tel:(contactopt)"]
messageVC.recipients = [String(contactopt)]

MessageComposeViewController only presents once

I'm using Xcode 8 to build an application for iPhone.My simple app has an button. When user tap on this button, messageComposeViewController is called and with phone number and message content filled.The message went through successfully when I clicked on Send button.The problem is MessageComposeViewController is showing only once.After the message sent, when I tapped on the button to call it, a black screen showed up instead of the message composer.My code is attached below. I appreciate any help.
import UIKit
import MessageUI
class ViewController: UIViewController, MFMessageComposeViewControllerDelegate {
let msg = MFMessageComposeViewController()
#IBOutlet weak var coordinate_label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func sendMessage(_ sender: AnyObject) {
self.msg.body = "Message Content"
self.msg.recipients = ["xxx-xxx-xxxx"]
self.msg.messageComposeDelegate = self
self.present(msg, animated: false, completion: nil)
}
func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) {
switch result.rawValue {
case MessageComposeResult.cancelled.rawValue:
dismiss(animated: true, completion: nil)
case MessageComposeResult.failed.rawValue:
dismiss(animated: true, completion: nil)
case MessageComposeResult.sent.rawValue:
dismiss(animated: true, completion: nil)
default:
break;
}
}
}
Try this code
import Foundation
import MessageUI
let textMessageRecipients = ["1-800-867-5309"] // for pre-populating the recipients list (optional, depending on your needs)
class MessageComposer: NSObject, MFMessageComposeViewControllerDelegate {
// A wrapper function to indicate whether or not a text message can be sent from the user's device
func canSendText() -> Bool {
return MFMessageComposeViewController.canSendText()
}
// Configures and returns a MFMessageComposeViewController instance
func configuredMessageComposeViewController() -> MFMessageComposeViewController {
let messageComposeVC = MFMessageComposeViewController()
messageComposeVC.messageComposeDelegate = self // Make sure to set this property to self, so that the controller can be dismissed!
messageComposeVC.recipients = textMessageRecipients
messageComposeVC.body = "Hey friend - Just sending a text message in-app using Swift!"
return messageComposeVC
}
// MFMessageComposeViewControllerDelegate callback - dismisses the view controller when the user is finished with it
func messageComposeViewController(controller: MFMessageComposeViewController!, didFinishWithResult result: MessageComposeResult) {
controller.dismissViewControllerAnimated(true, completion: nil)
}
}
Note, latest syntax 2017 ..
func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) {
controller.dismiss(animated: true, completion: nil)
}
In Your viewController ..
import UIKit
class ViewController: UIViewController {
// Create a MessageComposer
let messageComposer = MessageComposer()
#IBAction func sendTextMessageButtonTapped(sender: UIButton) {
// Make sure the device can send text messages
if (messageComposer.canSendText()) {
// Obtain a configured MFMessageComposeViewController
let messageComposeVC = messageComposer.configuredMessageComposeViewController()
// Present the configured MFMessageComposeViewController instance
// Note that the dismissal of the VC will be handled by the messageComposer instance,
// since it implements the appropriate delegate call-back
presentViewController(messageComposeVC, animated: true, completion: nil)
} else {
// Let the user know if his/her device isn't able to send text messages
let errorAlert = UIAlertView(title: "Cannot Send Text Message", message: "Your device is not able to send text messages.", delegate: self, cancelButtonTitle: "OK")
errorAlert.show()
}
}
}

Sending SMS from Contacts Fails

I am implementing a seemingly trivial and very popular use case where users select a contact, and send them a precomposed SMS.
However, the SMS ViewController dismisses itself automatically. This is easily reproducible.
How do I fix this?
Here's my code:
import UIKit
import MessageUI
import ContactsUI
class ViewController: UIViewController, MFMessageComposeViewControllerDelegate, CNContactPickerDelegate{
let contactPickerViewController = CNContactPickerViewController()
let messageVC = MFMessageComposeViewController()
override func viewDidLoad() {
super.viewDidLoad()
contactPickerViewController.delegate = self
messageVC.messageComposeDelegate = self
}
func contactPicker(picker: CNContactPickerViewController, didSelectContact contact: CNContact) {
if let phoneNumberValue = contact.phoneNumbers.first?.value as? CNPhoneNumber {
if let phoneNumber = phoneNumberValue.valueForKey("digits") as? String {
// Configure message ViewController
messageVC.recipients = [phoneNumber]
messageVC.body = "Yoyoyo"
picker.presentViewController(messageVC, animated: true, completion: nil)
}
}
}
func messageComposeViewController(controller: MFMessageComposeViewController, didFinishWithResult result: MessageComposeResult) {
self.dismissViewControllerAnimated(true, completion: nil)
}
#IBAction func invite(sender: AnyObject) {
self.presentViewController(self.contactPickerViewController, animated: true, completion: nil)
}
}
The problem is that you are asking your picker to present the message view controller. When contactPicker:picker:didSelectContact: method is called, the picker view controller is automatically being dismissed by the system. This means that the view controller is going away and you are trying to use that view controller to present your next view controller.
What you need to do is have "ViewController" in this case present the message view controller. Below is an example of the portion of your code i changed. You'll notice i have a timer there. This is because if you try to present the messageVC right away, nothing will happen because the contacts view controller isn't done dismissing itself yet.
func contactPicker(picker: CNContactPickerViewController, didSelectContact contact: CNContact) {
if let phoneNumberValue = contact.phoneNumbers.first?.value as? CNPhoneNumber {
if let phoneNumber = phoneNumberValue.valueForKey("digits") as? String {
// Configure message ViewController
messageVC.recipients = [phoneNumber]
messageVC.body = "Yoyoyo"
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.presentViewController(self.messageVC, animated: true, completion: nil)
})
}
}
}

Resources