POST EDITED
I have a CheckoutViewController that I copied from the Stripe git repository and I implemented it into my app. At first I was trying to setup the STPPaymentContext in a different vc but it was giving a bad access but now when I try to set it up in the Checkout vc, I get an assertion failure saying the JSON couldn't be parsed.
This is what I have in my MyAPIClient class:
class MyAPIClient: NSObject, STPCustomerEphemeralKeyProvider {
let baseURL = "https://us-central1-attend-41f12.cloudfunctions.net/createEphemeralKeys"
let ticketVC: TicketFormViewController = TicketFormViewController()
func createCustomerKey(withAPIVersion apiVersion: String, completion: #escaping STPJSONResponseCompletionBlock) {
ticketVC.getUsersStripeCustomerID { (customerid) in
if let id = customerid {
let url = URL(string:self.baseURL)!
var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false)!
urlComponents.queryItems = [URLQueryItem(name: "api_version", value: apiVersion), URLQueryItem(name: "customer_id", value: id)]
var request = URLRequest(url: urlComponents.url!)
request.httpMethod = "POST"
let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
guard let response = response as? HTTPURLResponse,
response.statusCode == 200,
let data = data,
let json = ((try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any]) as [String : Any]??) else {
completion(nil, error)
return
}
completion(json, nil)
})
task.resume()
}
}
}
}
This is my Cloud Functions function that I created to try and get the ephemeral key:
exports.createEphemeralKeys = functions.https.onRequest(async (req,
res) => {
var api_version = req.body.api_version;
var customerId = req.body.customer_id;
if (!api_version) {
res.status(400).end();
return;
}
let key = await stripe.ephemeralKeys.create(
{ customer: customerId },
{ stripe_version: api_version }
);
res.json(key);
});
This is looking like it's causing the problem, I know it's not the URL because I made another API call this morning with a paymentIntent Cloud Function and it had a 200 Status Code. I copied the code from the Stripe docs and had faith that it would work but it let me down. Any suggestions.
UPDATE I also checked the Cloud Functions server logs, and the function is executing with a 400 Error Status Code, so it's definitely the Cloud Function that is the issue, isn't the json in the exports.createEphemeralKeys function unmodified already, what else do I need to add for it to work?
After days of just trying to figure it out, I finally got help from a member in the Slack chat.
I got rid of the if statement, changed stripe_version to apiVersion because it was deprecated.
exports.createEphemeralKeys = functions.https.onRequest(async (req, res) => {
var api_version = req.query.api_version;
var customerId = req.query.customer_id;
const key = await stripe.ephemeralKeys.create(
{ customer: customerId },
{ apiVersion: api_version}
);
res.json(key);
});
I also changed req.body to req.query. The JSON now prints in the console, but there's still a lot left I need to figure out.
Related
I have an application where user can update their profile picture.
The application is developed in SwiftUI and used Alamofire to perform API request and the server is developed with Vapor.
When I tried to send the picture to the server, I got this error:
[ WARNING ] Value required for key 'filename'. [request-id: A5083FA1-657C-4777-A7FF-9D02E2A66703]
Here is the code from Vapor:
private func updatePicture(req: Request) async throws -> Response {
let file = try req.content.decode(File.self)
guard let fileExtension = file.extension else { throw Abort(.badRequest)}
return .init(status: .accepted, headers: getDefaultHttpHeader(), body: .empty)
}
And here is the iOS code:
func uploadFiles(urlParams: [String], method: HTTPMethod, user: User, image: UIImage, completionHandler: #escaping ((Data?, HTTPURLResponse?, Error?)) -> Void) {
guard let formattedUrl = URL(string: "\(url)/\(urlParams.joined(separator: "/"))") else {
completionHandler((nil, nil, nil))
return
}
var headers: HTTPHeaders?
headers = ["Authorization" : "Bearer \(user.token)"]
let multiPart: MultipartFormData = MultipartFormData()
multiPart.append(image.jpegData(compressionQuality: 0.9), withName: "data", fileName: "filename", mimeType: "image/jpeg" )
AF.upload(multipartFormData: multiPart, to: formattedUrl, method: .patch, headers: headers).response { data in
print(data)
}.resume()
}
I followed vapor and Alamofire documentation and I still get this issue.
Is anyone can help me with this issues ?
On the Vapor side you have to use struct with File field inside
struct PayloadModel: Content {
let data: File
}
private func updatePicture(req: Request) async throws -> HTTPStatus {
let payload = try req.content.decode(PayloadModel.self)
guard let fileExtension = payload.data.extension else {
throw Abort(.badRequest)
}
return .accepted
}
So my ultimate goal is to be able to just make test payments with Apple Pay on Stripe, whether that be with a token or something else.
**EDIT **I have this function I use to gather card info from the stored card in the Wallet:
func applePayContext(_ context: STPApplePayContext, didCreatePaymentMethod paymentMethod: STPPaymentMethod, paymentInformation: PKPayment, completion: #escaping STPIntentClientSecretCompletionBlock) {
guard let paymentIntentClientSecret = paymentIntentClientSecret else {
return;
}
let backendUrlForToken = "https://us-central1-xxxxxx-41f12.cloudfunctions.net/createStripeToken"
let url = URL(string: backendUrlForToken)
let pkToken = String(data: paymentInformation.token.paymentData, encoding: .utf8)
guard let name = paymentInformation.billingContact?.name else { return }
let nameFormatter = PersonNameComponentsFormatter()
nameFormatter.string(from: name)
let json: [String: Any] = [
"card": [
"address_city": paymentInformation.billingContact?.postalAddress?.city,
"address_country": paymentInformation.billingContact?.postalAddress?.country,
"address_line1": paymentInformation.billingContact?.postalAddress?.street,
"address_state": paymentInformation.billingContact?.postalAddress?.state,
"address_zip": paymentInformation.billingContact?.postalAddress?.postalCode,
"name": name
],
"muid": UIDevice.current.identifierForVendor?.uuidString,
"pk_token": pkToken,
"pk_token_instrument_name": paymentInformation.token.paymentMethod.displayName,
"pk_token_payment_network": paymentInformation.token.paymentMethod.network?.rawValue,
"pk_token_transaction_id": paymentInformation.token.transactionIdentifier
]
var request = URLRequest(url: url!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try? JSONSerialization.data(withJSONObject: json)
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let response = response as? HTTPURLResponse,
response.statusCode == 200,
let data = data,
let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
let token = json["id"] as? String else {
print("Error getting Stripe token")
return
}
print("\(token)")
self.stripeToken = token
}
task.resume()
let error = NSError()
completion(paymentIntentClientSecret, error)
}
I didn't have an endpoint for the API call so I created this request for a token. This is the function I have at my API endpoint:
exports.createStripeToken = functions.https.onRequest(async (req, res) => {
var cardAddressCity = req.body.card.address_city;
var cardAddressCountry = req.body.card.address_country;
var cardAddressLine = req.body.card.address_line1;
var cardAddressProvince = req.body.card.address_state;
var cardAddressPostalCode = req.body.card.address_zip;
var cardHolderName = req.body.card.name;
var muid = req.body.muid;
var pkToken = req.body.pk_token;
var pkTokenInstrument = req.body.pk_token_instrument_name;
var pkTokenNetwork = req.body.pk_token_payment_network;
var pkTokenTransactionID = req.body.pk_token_transaction_id;
const token = await stripe.tokens.create({
card: {
"address_city": cardAddressCity,
"address_country": cardAddressCountry,
"address_line1": cardAddressLine,
"address_state": cardAddressProvince,
"address_zip": cardAddressPostalCode,
"name": cardHolderName
},
"muid": muid,
"pk_token": pkToken,
"pk_token_instrument_name": pkTokenInstrument,
"pk_token_payment_network": pkTokenNetwork,
"pk_token_transaction_id": pkTokenTransactionID
});
res.send({
id: token.id,
});
});
I'm not sure if this is the correct way, I can't find much on the internet about this at all.
I figured this was the parameters I seen in my api logs so I used the same ones and I also seen a rare post on gist.github of a guy making an API call similar to this one, but for some reason it still doesn't work at all.
Your statements/logs aren't being hit because Token creation internally in STPApplePayContext is failing. For background, STPApplePayContext does:
Create a Token from the Apple Pay encrypted card details.
Using the Token, creates a PaymentMethod object.
Then triggers the didCreatePaymentMethod() delegate implementation.
And step 1 is failing.
Typically when I've seen a Token creation request 500, that typically means there might be a mismatch on the merchant ID used on XCode vs the certificate set up on Stripe account. Or it could be some combination of a PKPaymentNetwork not being supported on a Stripe account country.
I would re-do the steps of setting up the merchant ID and Apple Pay certificate, ideally on a fresh project to do away with any confusion or conflicts etc.
Since this was a 500, Stripe Support would be the right people to deal with that, as the error possibly lies on their end. I would provide them request IDs for your /v1/tokens creation request.
Currently looking to make an authentication request on the PredictHQ API using Alamofire.
I have generated client credentials in the developer's console, and transferred them to my project. The problem lies when I use the URL https://api.predicthq.com/oauth2/token/ in my function *receiveJSONData() to receive a network status of my requests.
Below are examples I followed from the PredictHQ website https://developer.predicthq.com/oauth2/ on how the cURL request should be formatted as.
1) I first created my networkServiceClient class
import UIKit
import Alamofire
class networkServiceClient {
private let token = "GENERATED_TOKEN_FROM_PREDICTHQ_API".data(using: String.Encoding.utf8)!.base64EncodedString()
private let secret = "GENERATED_SECRET_KEY_FROM_PREDICTHQ_API".data(using: String.Encoding.utf8)!.base64EncodedString()
private let id = "GENERATED_ID_FROM_PREDICTHQ_API".data(using: String.Encoding.utf8)!.base64EncodedString()
private let contentType = "application/json"
private var authURL = URL(string: "https://api.predicthq.com/oauth2/token/")
private var tokenDataURL = URL(string: "https://api.predicthq.com/v1/events/")
typealias webResponse = ([[String: Any]]?, Error?) -> Void
func receiveJSONData(completion: #escaping webResponse){
let loginString = String(format: "Basic %#:%#", id, secret)
let postHeaders:HTTPHeaders = ["Authorization": loginString, "Accept": contentType]
let params: [String : Any] = ["grant_type": "client_credentials", "scope": "account events signals"]
//post authentication request
AF.request(authURL!, method: .post, parameters: params, headers: postHeaders).responseJSON { (response) in
if let error = response.error {
completion(nil, error)
} else if let jsonArray = response.value as? [[String: Any]] {
completion(jsonArray, nil)
} else if let jsonDict = response.value as? [String: Any] {
completion([jsonDict], nil)
}
}
}
2) Then I implemented it in my TestingViewingController
import UIKit
import Alamofire
class TestingViewController: UIViewController {
private let networkingClient = networkServiceClient()
override func viewDidLoad() {
super.viewDidLoad()
networkingClient.receiveJSONData() { (json, error) in
if let error = error {
print(error.localizedDescription)
} else if let json = json {
print(json.description)
}
}
}
}
3) Lastly, here is my output in the TestingViewController console.
"error": invalid_client
Hey it might be because you're base64 encoding the client_id and secret separately but they should be encoded together (separated by colon) like the screenshot shows.
I am new to swift programming and need bit of your help forgive me if i am asking something stupid. I am trying call a function from my UIViewController for a POST request to API. Calling function is like this
#IBAction func actionStartSignIn(sender: AnyObject) {
let email: String = txtEmail.text!
let password: String = txtPassword.text!
if !email.isEmpty && !password.isEmpty && General.isValidEmail(email) && password.characters.count>6{
var request = RequestResponse()
request.email = email
request.password = password
let isValid = NSJSONSerialization.isValidJSONObject(request)
print(isValid)
var requestBody: String = ""
// Facing issue in following line
RequestManager.sharedInstance.postRequest(Constants.BASE_URL + Constants.LOGIN, body: requestBody, onCompletion: {(json: JSON) in{
let result = json["response"]
print(result)
}
}
)
}
}
And Called Function is like this
func postRequest(route: String, body: String, onCompletion: (JSON) -> Void) {
makeHTTPPostRequest(route, requestBody: body, onCompletion: { json, err in
onCompletion(json as JSON)
})
}
Further,
// MARK: Perform a POST Request
private func makeHTTPPostRequest(path: String, requestBody: String, onCompletion: ServiceResponse) {
let request = NSMutableURLRequest(URL: NSURL(string: path)!)
// Set the method to POST
request.HTTPMethod = "POST"
do {
// Set the POST body for the request
// let jsonBody = try NSJSONSerialization.dataWithJSONObject(body, options: .PrettyPrinted)
// request.HTTPBody = jsonBody
request.HTTPBody = requestBody.dataUsingEncoding(NSUTF8StringEncoding);
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
if let jsonData = data {
let json:JSON = JSON(data: jsonData)
onCompletion(json, nil)
} else {
onCompletion(nil, error)
}
})
task.resume()
}/* catch {
// error
onCompletion(nil, nil)
}*/
}
and
typealias ServiceResponse = (JSON, NSError?) -> Void
I am facing "Expression resolves to an unused function" while calling
RequestManager.sharedInstance.postRequest(Constants.BASE_URL + Constants.LOGIN, body: requestBody, onCompletion: {(json: JSON) in{ let result = json["response"] print(result) } } )
May be i am missing some basic syntax. Any help will be really appreciated.
Thank You.
Remove the { } phase after the in will solve the problem.
It should look like this:
RequestManager.sharedInstance.postRequest(Constants.BASE_URL + Constants.LOGIN, body: requestBody, onCompletion: {(json: JSON) in
let result = json["response"]
print(result)
}
)
For the closure param, you should not type it by yourself to prevent typo. Use tab key to select that param, then press enter, xCode will auto generate the code for you.
If use the way I just said, the trailing closure will look like this:
RequestManager.sharedInstance.postRequest(Constants.BASE_URL + Constants.LOGIN, body: requestBody) { (json) in
let result = json["response"]
print(result)
}
I try to use Twilio as an service provider but they have no examples for Swift that I understand.
My task is to send SMS to a number using Twilio API with Swift.
I have a Twilio.com account - and that one is working. But how do I do this in Swift code in a easy manner.
Twilio does provide a library - but that is meant for C# not for Swift (and using a bridging header seems too complicated!)
Here is the C# example, I need a easy Swift example.
// 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);
}
}
Twilio evangelist here.
To send a text message from Swift you can just make a request directly to Twilios REST API. That said, I would not recommend doing this from an iOS app (or any other client app) as it requires you to embed your Twilio account credentials in the app, which is dangerous. I would instead recommend sending the SMS from a server side application.
If you do want to send the message from your app, there are a couple of Swift libraries I know of that simplify making HTTP requests:
Alamofire - from Mattt Thompson, creator of AFNetworking - used in the example here: https://www.twilio.com/blog/2016/11/how-to-send-an-sms-from-ios-in-swift.html
SwiftRequest - from Ricky Robinett of Twilio
To make the request using SwiftRequest, it would look like this:
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)")
}
});
Hope that helps.
recently I have gone through Twilio docs and few SO post.
you can send SMS with following code snip in 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()
}
if everything goes fine..You should receive message like this..
Here is the new Swift example for Passwordless authentication. For the complete tutorial, Click Here
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");
}
})
If You are using server side Swift with Perfect.org
See this Blog
http://perfecttwilio.blogspot.in
The answer by "Devin Rader" is perfect. For any other users like me, the following is the full converted code for SwiftRequest for swift 3.0. The original code is by Ricky Robinett.
Please let us know if any errors.
Thankx..
//
// 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
}
}
Sample code to use above class as mentioned by "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))")
}
});
Swift 3 version:
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()
}