Надсилання SMS в iOS за допомогою Swift


78

Перш за все, я справді здивований, що це не дублікат, тому що є ТОНИ запитань щодо stackoverflow, які вирішують це в Objective-C, але я ще не побачив хорошої відповіді, яка використовувала Swift.

Я шукаю фрагмент коду в Swift, який надсилає довільний рядок як тіло текстового повідомлення на вказаний номер телефону. За суті, я хотів би що - щось на зразок цього з офіційної документації Apple, але в Swift замість Objective-C.

Я думаю, це не надто складно, оскільки це можна зробити лише за кілька рядків коду в Android.

EDIT: Я шукаю 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

2
Я також хотів би вказати на той факт, що це питання є тим самим питанням для Objective-C, воно отримало понад 300 голосів проти і було захищене модераторами (не було утримано, як моє). Я вважаю, що це питання насправді може стати досить цінним для громади.
johncorser

6
Зрозуміло. Я новачок у iOS і не мав можливості вивчити ціль C. Переклад може бути простим, як тільки ти дізнаєшся, як це робиться, але я не знаю, як це робиться. Фрагмент, швидше за все, буде використовуватися багатьма іншими, як я.
johncorser

1
Звичайно, але принаймні, здається дивним писати код Swift і посилатися на відповіді на Objective-C. Потім читач повинен виконати перетворення, а не повторно використовувати фрагмент. Створення репертуару відповідей Swift на StackOverflow буде корисним лише для спільноти в майбутньому, оскільки Swift з часом може стати основною мовою, на якій написані програми для iOS.
johncorser

2
Запитанню, яке я поставив, 6 років, але мова Свіфта набагато молодша. Швидку версію питання не можна було задавати шість років тому.
johncorser

Відповіді:


129

Не впевнений, що ви дійсно отримали відповідь. Я був у подібному полюванні, натрапив на це рішення і привів його до роботи.

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
Орен Едріч,

2
Ви просто перейдете до програми обміну повідомленнями. Додаток визначає, чи це повідомлення або iMessage.
sivag1

Як поділитися URL-адресою та текстом?
kishor0011

Подумайте про оновлення для Swift для. Наприклад, зараз: func messageComposeViewController (_ контролер: MFMessageComposeViewController, ...)
crimson_penguin

працював у мене з невеликим редагуванням. controller.recipients = ([self.phoneNumber.text] as! [String])
Ракшіта Муранга Родріго

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

Для надсилання iMessage у Swift 5 я використовую наступний код

Просто упакуйте 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 (анімоване: true, завершення: nil)
Девід Санфорд,

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 дозволить тексту заповнювача стати зеленим, не збігатися з номером у контактах, а потім дозволити користувачеві надіслати повідомлення на зразок тексту, яке нікуди не дінеться. (Можливо , що варто було повідомлення користувача пристрою, якщо заряди носіїв для нього.)
BENČ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.