I'm trying to send a request to the SendGrid API using Swift 4 and URLSession
. My hope is to not include any third-party dependencies since this is the only place in my app where I use JSON and an HTTP request.
Since SendGrid doesn't have any Swift examples, I'm looking at the cURL sample:
curl --request POST \
--url https://api.sendgrid.com/v3/mail/send \
--header "Authorization: Bearer $SENDGRID_API_KEY" \
--header 'Content-Type: application/json' \
--data '{"personalizations": [{"to": [{"email": "[email protected]"}]}],"from": {"email": "[email protected]"},"subject": "Sending with SendGrid is Fun","content": [{"type": "text/plain", "value": "and easy to do anywhere, even with cURL"}]}'
I think I have everything arranged except I'm unsure how to encode the data
portion into valid JSON for the request. I tried converting it to a Dictionary
, but it doesn't work. Here's my code:
let sendGridURL = "https://api.sendgrid.com/v3/mail/send"
var request = URLRequest(url: URL(string: sendGridURL)!)
request.httpMethod = "POST"
//Headers
request.addValue("Bearer \(sendGridAPIKey)", forHTTPHeaderField: "Authorization")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
//Data
let json = [
"personalizations":[
"to": ["email":"[email protected]"],
"from": ["email":"[email protected]"],
"subject": "Sending with SendGrid is Fun",
"content":["type":"text/plain", "value":"and easy to do anywhere, even with Swift"]
]
]
let data = try! JSONSerialization.data(withJSONObject: json, options: [])
let ready = try! JSONEncoder().encode(data) <-- !!! Crash !!!
request.httpBody = ready
Has anyone pulled this same thing off from a Swift app that can help me out?
Update
For anyone trying to do the same thing, I had to adjust my JSON to look like this in order for it to be formatted correctly for SendGrid:
let json:[String:Any] = [
"personalizations":[["to": [["email":"[email protected]"]]]],
"from": ["email":"[email protected]"],
"subject": "Sending with SendGrid is Fun",
"content":[["type":"text/plain", "value":"and easy to do anywhere, even with Swift"]]
]
There's no need to encode the JSON data twice. Remove this line
let ready = try! JSONEncoder().encode(data) // <-- !!! Crash !!!
and simply do
do {
let data = try JSONSerialization.data(withJSONObject: json, options: [])
request.httpBody = data
} catch {
print("\(error)")
}
Also, don't use try!
if you can avoid it.