Sending SMS in iOS with Swift

First of all, I'm really surprised that this is not a duplicate, because there are TONS of stackoverflow questions that solve this in Objective-C, but I have yet to see a good answer that used Swift.

What I'm looking for is a code snippet in Swift that sends an arbitrary string as a the body of a text message to given phone number. Essentially, I'd like something like this from Apple's official documentation, but in Swift instead of Objective-C.

I imagine this isn't too difficult, as it can be done in just a couple of lines of code in Android.

EDIT: What I'm looking for is 5-20 lines of Swift code, I do not agree that this is too broad. In Java (for Android), the solution looks like this:

package com.company.appname;
import android.app.Activity;
import android.telephony.SmsManager;
public class MainActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); public static final mPhoneNumber = "1111111111"; public static final mMessage = "hello phone"; SmsManager.getDefault().sendTextMessage(mPhoneNumber, null, mMessage, null, null); }
}

Now this is the android solution, and it's only 11 lines. Java tends to be much more verbose than Swift, so I doubt what I'm asking is "too broad", it is more likely that I don't know how to use the Objective-C MessageComposer object, because the documentation that I linked to above is unclear with regard to usage in Swift.

9

7 Answers

Not sure if you really got the answer. I was in a similar hunt and came across this solution and got it to work.

import UIKit
import MessageUI
class ViewController: UIViewController, MFMessageComposeViewControllerDelegate { @IBOutlet weak var phoneNumber: UITextField! override func viewDidLoad() { super.viewDidLoad() } @IBAction func sendText(sender: UIButton) { if (MFMessageComposeViewController.canSendText()) { let controller = MFMessageComposeViewController() controller.body = "Message Body" controller.recipients = [phoneNumber.text] controller.messageComposeDelegate = self self.presentViewController(controller, animated: true, completion: nil) } } func messageComposeViewController(controller: MFMessageComposeViewController!, didFinishWithResult result: MessageComposeResult) { //... handle sms screen actions self.dismissViewControllerAnimated(true, completion: nil) } override func viewWillDisappear(animated: Bool) { self.navigationController?.navigationBarHidden = false }
}
5

Swift 3.0 Solution:

func sendSMSText(phoneNumber: String) { if (MFMessageComposeViewController.canSendText()) { let controller = MFMessageComposeViewController() controller.body = "" controller.recipients = [phoneNumber] controller.messageComposeDelegate = self self.present(controller, animated: true, completion: nil) } } func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) { //... handle sms screen actions self.dismiss(animated: true, completion: nil) } override func viewWillDisappear(_ animated: Bool) { self.navigationController?.isNavigationBarHidden = false }
0

For sending iMessage in Swift 5 I use following code

Just MessageUI package and implement MFMessageComposeViewControllerDelegate

import UIKit
import MessageUI
class ViewController: UIViewController, MFMessageComposeViewControllerDelegate { override func viewDidLoad() { super.viewDidLoad() } @IBAction func sendNewIMessage(_ sender: Any) { let messageVC = MFMessageComposeViewController() messageVC.body = "Enter a message details here"; messageVC.recipients = ["recipients_number_here"] messageVC.messageComposeDelegate = self self.present(messageVC, animated: true, completion: nil) } func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) { switch (result) { case .cancelled: print("Message was cancelled") case .failed: print("Message failed") case .sent: print("Message was sent") default: return } dismiss(animated: true, completion: nil) }
}
1

Simpler solution may be opening html link:

let mPhoneNumber = "1111111111";
let mMessage = "hello%20phone";
if let url = URL(string: "sms://" + mPhoneNumber + "&body="+mMessage) { UIApplication.shared.open(url)
}

Make sure you replaced spaces with "%20"

Swift 3, 4, 5

@IBAction func sendSmsClick(_ sender: AnyObject) { guard MFMessageComposeViewController.canSendText() else { return } let messageVC = MFMessageComposeViewController() messageVC.body = "Enter a message"; messageVC.recipients = ["Enter tel-nr"] messageVC.messageComposeDelegate = self; self.present(messageVC, animated: false, completion: nil) } 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; } }

UI will look like:enter image description here

If you do not want to depend on an UIViewController, follows a Swift 3.0 solution:

import UIKit
import MessageUI
class ECMMessageComposerBuilder: NSObject { private dynamic var customWindow: UIWindow? private var body: String? private var phoneNumber: String? fileprivate var messageController: MFMessageComposeViewController? var canCompose: Bool { return MFMessageComposeViewController.canSendText() } func body(_ body: String?) -> ECMMessageComposerBuilder { self.body = body return self } func phoneNumber(_ phone: String?) -> ECMMessageComposerBuilder { self.phoneNumber = phone return self } func build() -> UIViewController? { guard canCompose else { return nil } messageController = MFMessageComposeViewController() messageController?.body = body if let phone = phoneNumber { messageController?.recipients = [phone] } messageController?.messageComposeDelegate = self return messageController } func show() { customWindow = UIWindow(frame: UIScreen.main.bounds) customWindow?.rootViewController = MNViewController() // Move it to the top let topWindow = UIApplication.shared.windows.last customWindow?.windowLevel = (topWindow?.windowLevel ?? 0) + 1 // and present it customWindow?.makeKeyAndVisible() if let messageController = build() { customWindow?.rootViewController?.present(messageController, animated: true, completion: nil) } } func hide(animated: Bool = true) { messageController?.dismiss(animated: animated, completion: nil) messageController = nil customWindow?.isHidden = true customWindow = nil }
}
extension ECMMessageComposerBuilder: MFMessageComposeViewControllerDelegate { func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) { controller.dismiss(animated: true, completion: nil) hide() }
}

You call the composer this way:

let phoneNumber = "987654321"
let composer = MNMessageComposerBuilder()
composer.phoneNumber(phoneNumber).show()

or using a lazy var

let phoneNumber = "987654321"
private lazy var messageComposer: MNMessageComposerBuilder = { let composer = MNMessageComposerBuilder() return composer
}()
messageComposer.phoneNumber(phoneNumber).show()
@IBAction func sendMessageBtnClicked(sender: AnyObject) { var messageVC = MFMessageComposeViewController() messageVC.body = "Enter a message"; messageVC.recipients = ["Enter tel-nr"] messageVC.messageComposeDelegate = self; self.presentViewController(messageVC, animated: false, completion: nil)
}
func messageComposeViewController(controller: MFMessageComposeViewController!, didFinishWithResult result: MessageComposeResult) { switch (result.value) { case MessageComposeResultCancelled.value: println("Message was cancelled") self.dismissViewControllerAnimated(true, completion: nil) case MessageComposeResultFailed.value: println("Message failed") self.dismissViewControllerAnimated(true, completion: nil) case MessageComposeResultSent.value: println("Message was sent") self.dismissViewControllerAnimated(true, completion: nil) default: break; }
}
1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like