使用Swift通过Twilio发送短信

9

我尝试使用Twilio作为服务提供商,但他们没有我能理解的Swift示例。

我的任务是使用Swift和Twilio API向一个号码发送短信。

我已经有了一个Twilio.com账户 - 它是有效的。但我该如何以简单的方式在Swift代码中实现这个功能呢?

Twilio提供了一个库 - 但那是针对C#而不是Swift的(使用桥接头似乎太复杂!)

这里是一个C#示例,我需要一个简单的Swift示例。

// Download the twilio-csharp library from twilio.com/docs/csharp/install
using System;
using Twilio;
class Example 
{
  static void Main(string[] args) 
  {
    // Find your Account Sid and Auth Token at twilio.com/user/account
    string AccountSid = "AC5ef8732a3c49700934481addd5ce1659";
    string AuthToken = "{{ auth_token }}";
    var twilio = new TwilioRestClient(AccountSid, AuthToken);


    var message = twilio.SendMessage("+14158141829", "+15558675309", "Jenny please?! I love you <3", new string[] {"http://www.example.com/hearts.png"});

    Console.WriteLine(message.Sid);
  }
}
6个回答

11

我是Twilio的布道者。

要从Swift发送文本消息,您可以直接向Twilios REST API发出请求。话虽如此,我不建议在iOS应用程序(或任何其他客户端应用程序)中执行此操作,因为它要求您将Twilio帐户凭据嵌入应用程序,这很危险。我建议从服务器端应用程序发送短信。

如果您确实想从应用程序发送消息,则我知道有一些Swift库可以简化HTTP请求:

使用SwiftRequest进行请求的代码如下:

var swiftRequest = SwiftRequest();

var data = [
    "To" : "+15555555555",
    "From" : "+15555556666",
    "Body" : "Hello World"
];

swiftRequest.post("https://api.twilio.com/2010-04-01/Accounts/[YOUR_ACCOUNT_SID]/Messages", 
    auth: ["username" : "[YOUR_ACCOUNT_SID]", "password" : "YOUR_AUTH_TOKEN"]
    data: data, 
    callback: {err, response, body in
        if err == nil {
            println("Success: \(response)")
        } else {
            println("Error: \(err)")
        }
});

希望这可以帮到你。


嗨,传教士Devin :-) 谢谢您的回答。我会考虑使用服务器端应用程序,但首先尝试这个以确保一切正常运作。 - Knut_Norway
1
你能指导我如何在Swift NSMutableURLRequest中使用**auth: ["username" : "[YOUR_ACCOUNT_SID]", "password" : "YOUR_AUTH_TOKEN"]**进行POST请求吗? - swiftBoy
嗨Devin,我正在使用你上面展示的SwiftRequest。我已经提供了我的plivo短信API试用凭据和相应的plivo API网址。但是我得到了状态码:401。你能告诉我可能的原因吗?这真的很有帮助。 - Pruthvi Hariharan
有人能告诉我如何检查用户是在线还是离线吗? - AbecedarioPoint

5

最近我查阅了Twilio文档和一些SO文章。

您可以使用以下Swift 2.0代码片段发送短信

func sendSMS()
    {

        let twilioSID = "your Sender ID here"
        let twilioSecret = "your token id here"

        //Note replace + = %2B , for To and From phone number
        let fromNumber = "%2B14806794445"// actual number is +14803606445
        let toNumber = "%2B919152346132"// actual number is +919152346132
        let message = "Your verification code is 2212 for signup with <app name here> "

        // Build the request
        let request = NSMutableURLRequest(URL: NSURL(string:"https://\(twilioSID):\(twilioSecret)@api.twilio.com/2010-04-01/Accounts/\(twilioSID)/SMS/Messages")!)
        request.HTTPMethod = "POST"
        request.HTTPBody = "From=\(fromNumber)&To=\(toNumber)&Body=\(message)".dataUsingEncoding(NSUTF8StringEncoding)

        // Build the completion block and send the request
        NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data, response, error) in
            print("Finished")
            if let data = data, responseDetails = NSString(data: data, encoding: NSUTF8StringEncoding) {
                // Success
                print("Response: \(responseDetails)")
            } else {
                // Failure
                print("Error: \(error)")
            }
        }).resume()
}

如果一切顺利,您应该会收到这样的消息:

enter image description here


我收到了这个响应。来自电话号码+254....的号码不是您账户的有效短信接收电话号码或短代码。我正在使用试用账户。请问您能建议我该怎么做吗? - Niharika
有人能告诉我如何检查用户是在线还是离线吗? - AbecedarioPoint

0

这里是关于无密码认证的全新 Swift 示例。如需完整教程,请点击此处

let url = "http://localhost:8000"
  var swiftRequest = SwiftRequest()
  var params:[String:String] = [
    "token" : token!.text
  ]

  swiftRequest.post(url + "/user/auth/", data: params, callback: {err, response, body in
    if( err == nil && response!.statusCode == 200) {
      if((body as NSDictionary)["success"] as Int == 1) {
        self.showAlert("User successfully authenticated!");
      } else {
        self.showAlert("That token isn't valid");
      }
    } else {
      self.showAlert("We're sorry, something went wrong");
    }
  })

0

"Devin Rader"的回答非常完美。对于像我这样的其他用户,以下是SwiftRequest在swift 3.0中的完整转换代码。原始代码由Ricky Robinett提供。

如果有任何错误,请告诉我们。

谢谢。

//
//  SwiftRequest.swift
//  SwiftRequestTest
//
//  Created by Ricky Robinett on 6/20/14.
//  Copyright (c) 2015 Ricky Robinett. All rights reserved.
//
// ***********************************************************
//
// Modification for Swift 3.0 by Sanjay Sampat on 21.Jun.2017
//
// ***********************************************************

import Foundation

public class SwiftRequest {
    var session = URLSession.shared

    public init() {
        // we should probably be preparing something here...
    }

    // GET requests
    public func get(url: String, auth: [String: String] = [String: String](), params: [String: String] = [String: String](), callback: ((_ err: NSError?, _ response: HTTPURLResponse?, _ body: AnyObject?)->())? = nil) {
        let qs = dictToQueryString(data: params)
        request(options: ["url" : url, "auth" : auth, "querystring": qs ], callback: callback )
    }

    // POST requests
    public func post(url: String, data: [String: String] = [String: String](), auth: [String: String] = [String: String](), callback: ((_ err: NSError?, _ response: HTTPURLResponse?, _ body: AnyObject?)->())? = nil) {
        let qs = dictToQueryString(data: data)
        request(options: ["url": url, "method" : "POST", "body" : qs, "auth" : auth] , callback: callback)
    }

    // Actually make the request
    func request(options: [String: Any], callback: ((_ err: NSError?, _ response: HTTPURLResponse?, _ body: AnyObject?)->())?) {
        if( options["url"] == nil ) { return }

        var urlString = options["url"] as! String
        if( options["querystring"] != nil && (options["querystring"] as! String) != "" ) {
            let qs = options["querystring"] as! String
            urlString = "\(urlString)?\(qs)"
        }

        let url = NSURL(string:urlString)
        let urlRequest = NSMutableURLRequest(url: url! as URL)

        if( options["method"] != nil) {
            urlRequest.httpMethod = options["method"] as! String
        }

        if( options["body"] != nil && options["body"] as! String != "" ) {
            var postData = (options["body"] as! String).data(using: String.Encoding.ascii, allowLossyConversion: true)
            urlRequest.httpBody = postData
            urlRequest.setValue("\(postData!.count)", forHTTPHeaderField: "Content-length")
        }

        // is there a more efficient way to do this?
        if( options["auth"] != nil && (options["auth"] as! [String: String]).count > 0) {
            var auth = options["auth"] as! [String: String]
            if( auth["username"] != nil && auth["password"] != nil ) {
                let username = auth["username"]
                let password = auth["password"]
                var authorization = "\(username!):\(password!)"
                if let data = authorization.data(using: String.Encoding.utf8) {
                    //authorization = "Basic " + data.base64EncodedString(options: [])
                    authorization = "Basic " + data.base64EncodedString()
                }

                urlRequest.setValue(authorization, forHTTPHeaderField: "Authorization")
            }
        }

        let task = session.dataTask(with: urlRequest as URLRequest, completionHandler: {body, response, err in
            let resp = response as! HTTPURLResponse?

            if( err == nil) {
                if let gotResponse = response {
                if(gotResponse.mimeType == "text/html") {
                    let bodyStr = NSString(data: body!, encoding:String.Encoding.utf8.rawValue)
                    return callback!(err as NSError?, resp, bodyStr)
                } else if(gotResponse.mimeType == "application/xml") {
                    let bodyStr = NSString(data: body!, encoding:String.Encoding.utf8.rawValue)
                    return callback!(err as NSError?, resp, bodyStr)
                } else if(gotResponse.mimeType == "application/json") {
                    // ss pending
                    do {
                        let jsonAnyObject:AnyObject = try JSONSerialization.jsonObject(with: (body! as NSData) as Data, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String: AnyObject] as AnyObject
                        return callback!(err as NSError?, resp, jsonAnyObject as AnyObject);
                    } catch _ {
                    }
                }
            }
            }

            return callback!(err as NSError?, resp, body as AnyObject)
        })

        task.resume()
    }

    func request(url: String, callback: ((_ err: NSError?, _ response: HTTPURLResponse?, _ body: AnyObject?)->())? = nil) {
        request(options: ["url" : url ], callback: callback )
    }

    private func dictToQueryString(data: [String: String]) -> String {

        var qs = ""
        for (key, value) in data {
            let encodedKey = encode(value: key)
            let encodedValue = encode(value: value)
            qs += "\(encodedKey)=\(encodedValue)&"
        }
        return qs
    }

    private func encode(value: String) -> String {

        let queryCharacters =  NSCharacterSet(charactersIn:" =\"#%/<>?@\\^`{}[]|&+").inverted

        if let encodedValue:String = value.addingPercentEncoding(withAllowedCharacters: queryCharacters) {
            return encodedValue
        }

        //let encodedValue:String = value.stringByAddingPercentEncodingWithAllowedCharacters(queryCharacters)!

        return value
    }
}

使用上述类的示例代码,如“Devin Rader”所述

    let URL = "https://api.twilio.com/2010-04-01/Accounts/\(myUserIdForBulkSmsMessageSending)/Messages"         
    var swiftRequest = SwiftRequest();

    var data = [
        "To" : "+\(replaceNumberToSendSms)",
        "From" : "+\(replaceNumberFromSendSms)",
        "Body" : message,
        "MediaUrl" : theUrlEncodedMessage
    ];
    //print( "=========VV==========" )
    //print( "URL: \(URL) " )
    //print( "data: \(String(describing: data))" )
    //print( "auth: \(myUserIdForBulkSmsMessageSending)   \(myUserPasswordForBulkSmsMessageSending)")
    //print( "=====================" )
    swiftRequest.post(url: URL,
                      data: data,
                      auth: ["username" : myUserIdForBulkSmsMessageSending, "password" : myUserPasswordForBulkSmsMessageSending],
        callback: {err, response, body in
            if err == nil {
                print("Success: \(String(describing: response))")
                if let currentBody = body {

                    // SSTODO PENDING TO HANDLE SUCCESS OF TWILLO OR ERRORS HANDLING OF TWILLO.

                    //print( "=====================" )
                    //print( " currentBody:  \(currentBody) " )
                    //print( " currentBodyString: \(String(describing: currentBody)) ")
                    //print( "=========^^==========" )
                }
            } else {
                print("Error: \(String(describing: err))")
            }
    });

0

Swift 3 版本:

func sendSMS()
{
    print("Starting...")
    let twilioSID = "ENRET YOUR SID"
    let twilioSecret = "YOUR TOKEN"
    //Note replace + = %2B , for To and From phone number
    let fromNumber = "%29999999"// actual number is +9999999
    let toNumber = "%29999999"// actual number is +9999999
    let message = "Your verification code is 2212 for signup with"

    // Build the request
    let request = NSMutableURLRequest(url: URL(string:"https://\(twilioSID):\(twilioSecret)@api.twilio.com/2010-04-01/Accounts/\(twilioSID)/SMS/Messages")!)
    request.httpMethod = "POST"
    request.httpBody = "From=\(fromNumber)&To=\(toNumber)&Body=\(message)".data(using: .utf8)

    // Build the completion block and send the request
    URLSession.shared.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) in
        print("Finished")
        if let data = data, let responseDetails = NSString(data: data, encoding: String.Encoding.utf8.rawValue) {
            // Success
            print("Response: \(responseDetails)")
        } else {
            // Failure
            print("Error: \(error)")
        }
    }).resume()
}

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接