Отправка SMS на Swift (iOS/macOS): API и библиотеки
В разработке под iOS и macOS часто возникает необходимость отправлять SMS-сообщения — для верификации пользователей, отправки уведомлений или интеграции с CRM. В этой статье мы рассмотрим два основных подхода: использование встроенного фреймворка MessageUI для отправки SMS через системное приложение и интеграцию с облачными SMS-провайдерами (Twilio, Nexmo/Vonage) через HTTP API. Также обсудим ограничения и лучшие практики.
1. Отправка SMS через MessageUI (только iOS)
Фреймворк MessageUI предоставляет контроллер MFMessageComposeViewController, который позволяет отправить SMS из вашего приложения, используя стандартный интерфейс iOS. Важно: этот метод работает только на реальных устройствах (не в симуляторе) и требует активной SIM-карты.
Шаг 1: Подключение фреймворка
Добавьте импорт в файл, где будете работать с SMS:
import MessageUI
Шаг 2: Проверка возможности отправки
Перед вызовом контроллера обязательно проверьте, может ли устройство отправлять SMS:
if MFMessageComposeViewController.canSendText() {
// можно отправлять
} else {
// показать ошибку пользователю
}
Шаг 3: Создание и настройка контроллера
let messageVC = MFMessageComposeViewController()
messageVC.body = "Ваш код подтверждения: 123456"
messageVC.recipients = ["+79001234567"]
messageVC.messageComposeDelegate = self // не забудьте установить делегат
present(messageVC, animated: true, completion: nil)
Шаг 4: Реализация делегата
extension YourViewController: MFMessageComposeViewControllerDelegate {
func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) {
controller.dismiss(animated: true) {
switch result {
case .sent:
print("SMS отправлено")
case .cancelled:
print("Отменено")
case .failed:
print("Ошибка отправки")
@unknown default:
break
}
}
}
}
Ограничения:
- Не работает в симуляторе.
- Пользователь видит интерфейс и может изменить сообщение.
- Не подходит для автоматической отправки (например, серверной части).
- Недоступно на macOS (только iOS).
2. Отправка SMS через сторонние API (Twilio, Nexmo и др.)
Для серверной отправки SMS (без участия пользователя) используйте HTTP API облачных провайдеров. Рассмотрим пример с Twilio — одним из самых популярных сервисов.
Шаг 1: Получение учетных данных
Зарегистрируйтесь в Twilio, получите Account SID, Auth Token и номер телефона отправителя (например, +15005550006 для тестов).
Шаг 2: Отправка POST-запроса
Используйте URLSession для вызова API Twilio:
func sendSMSviaTwilio(to recipient: String, message: String) {
let accountSID = "YOUR_ACCOUNT_SID"
let authToken = "YOUR_AUTH_TOKEN"
let fromNumber = "+15005550006"
let urlString = "https://api.twilio.com/2010-04-01/Accounts/\(accountSID)/Messages.json"
guard let url = URL(string: urlString) else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
let loginString = "\(accountSID):\(authToken)"
let loginData = loginString.data(using: .utf8)!
let base64LoginString = loginData.base64EncodedString()
request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
let bodyParams = [
"From": fromNumber,
"To": recipient,
"Body": message
]
let bodyString = bodyParams.map { "\($0.key)=\($0.value)" }.joined(separator: "&")
request.httpBody = bodyString.data(using: .utf8)
URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print("Ошибка запроса: \(error?.localizedDescription ?? "неизвестная")")
return
}
if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 201 {
print("SMS успешно отправлено через Twilio")
} else {
print("Ошибка сервера: \(String(data: data, encoding: .utf8) ?? "")")
}
}.resume()
}
Альтернативы: Nexmo (Vonage) и другие
API других провайдеров работают аналогично — POST-запрос с базовой