使用Swift在iOS中发送短信


78

首先,我真的很惊讶这不是重复的,因为在Objective-C中有大量的堆栈溢出问题可以解决这个问题,但是我还没有看到使用Swift的好答案。

我正在寻找的是Swift中的代码段,该代码段将任意字符串作为文本消息的主体发送到给定的电话号码。从本质上讲,我希望像这样从苹果的官方文档,但是在斯威夫特,而不是Objective-C的。

我认为这并不难,因为可以在Android中仅用几行代码就可以完成。

编辑:我正在寻找的是5-20行Swift代码,我不同意这个范围太广。在Java(适用于Android)中,解决方案如下所示:

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);
     }
}

现在这是android解决方案,只有11行。Java往往比Swift更冗长,因此我怀疑我要问的是“范围太广”,很可能我不知道如何使用Objective-C MessageComposer对象,因为我链接的文档关于Swift中的用法,上述内容尚不清楚。


2
我已经编辑了帖子,我认为我想问的问题不太广泛。请重新考虑关闭此问题,或通过要求澄清我遗漏的细节来帮助我解决问题,这会使范围过大。
johncorser 2014年

2
我还想指出一个事实,这个问题对于Objective-C来说是相同的问题,获得了300多个投票,并且受到版主的保护(没有像我的一样被搁置)。我相信这个问题实际上可能对社区变得非常有价值。
johncorser 2014年

6
明白了 我是iOS的初学者,还没有机会学习ObjectiveC。一旦您知道它的完成方式,翻译就很容易了,但我不知道它是如何完成的。像我这样的其他人很可能会使用该代码段。
johncorser 2014年

1
当然可以,但是至少起码编写Swift代码并参考Objective-C答案似乎很奇怪。然后,读者必须进行转换,而不是重复使用代码段。将来在StackOverflow上建立Swift答案库只会对社区有所帮助,因为Swift最终可能会成为编写iOS应用程序的主要语言。
johncorser 2014年

2
我链接的问题已有6岁了,但是Swift语言要年轻得多。六年前还没有问过这个问题的快速版本。
johncorser 2014年

Answers:


127

不知道您是否真的得到了答案。我也遇到了类似的情况,遇到了这种解决方案并使它起作用。

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
    }
}

这会发送短信还是iMessage
Oren Edrich '01

2
它将带您直接进入Messaging应用程序。该应用程序确定这是消息还是iMessage。
sivag1

如何共享URL和文本?
kishor0011

考虑更新Swift。例如,现在是:func messageComposeViewController(_ controller:MFMessageComposeViewController,...)
crimson_penguin

很少编辑就为我工作。 controller.recipients = ([self.phoneNumber.text] as! [String])
Rakshitha Muranga Rodrigo

29

Swift 3.0解决方案:

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
    }

15

为了在Swift 5中发送iMessage,我使用以下代码

只是MessageUI包并实现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)
    }
}

谢谢,但是消息弹出窗口并没有关闭,因此我需要将控制器添加到以下行:controller.dismiss(animated:true,complete:nil)
David Sanford

5

如果您不想依赖UIViewController,请遵循Swift 3.0解决方案:

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()
    }
}

您通过以下方式调用作曲家:

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

或使用懒惰的变量

let phoneNumber = "987654321"
private lazy var messageComposer: MNMessageComposerBuilder = {
    let composer = MNMessageComposerBuilder()
    return composer
}()
messageComposer.phoneNumber(phoneNumber).show()

5

斯威夫特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;
        }
    }

用户界面如下所示: 在此处输入图片说明


0

更简单的解决方案可能是打开html链接:

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

确保用“%20”替换空格


-1
@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;
    }
}

这会在模拟器中崩溃,因为您无需检查canSendText()。同样,recipients将其放置在撰写窗口中。在大多数设备中,MMS将允许占位符文本变为绿色,无法与联系人中的数字匹配,然后让用户向您的示例文本发送一条消息,该消息将不起作用。(如果运营商收费,则可能使设备用户花费一条消息的费用。)
benc
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.