While trying to create an API manager for my projects, I came across an issue using URLComponents
. When I build my url using URLComponents
, I get a 400 status code from the API, but if I build a request using a URL I build manually, I get back status code 200 (and the data I requested). I've put together some code to duplicate my issue. In the code I am trying to access Yelp's API, but I also tested it using OpenWeather's API and I get the same codes. Is there something about URLComponents
that I'm not understanding? Thanks in advance.
import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
let baseUrl = "https://api.yelp.com/v3"
let apiKey = "Bearer <MY API KEY>"
let endpoint = "/businesses/search"
let query = ["location": "90120"]
let headers = ["Authorization": apiKey]
let fullURL = URL(string: baseUrl + endpoint + "?location=90210")
print("****** TRY USING URLComponents ******")
// set base url
var urlComponent = URLComponents(string: baseUrl)!
// add enpoint path
urlComponent.path = endpoint
// map all query items
urlComponent.queryItems = query.map {
URLQueryItem(name: $0, value: $1)
}
// build request based on url (should be baseUrl + endpoint + queries)
var request = URLRequest(url: urlComponent.url!)
// add headers
for (field, value) in headers {
request.addValue(value, forHTTPHeaderField: field)
}
// make the request
makeReq(request: request)
// ****** END URLComponents *******
//Wait 5 seconds then try without URLComponents
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
print("\n******* TRY WITHOUT URLComponents ***********")
// reset request using fullUrl variable
request = URLRequest(url: fullURL!)
// add headers
for (field, value) in headers {
request.addValue(value, forHTTPHeaderField: field)
}
// make the request, again
makeReq(request: request)
}
// make request function
func makeReq(request: URLRequest) {
// start session
let session = URLSession(configuration: .default)
var dt: Void = session.dataTask(with: request) { (data, response, error) in
/* if let responseString = String(bytes: data!, encoding: .utf8) {
print("Data:\n\(responseString)")
} else { print("Data: No Data") } */
if let httpResponse = response as? HTTPURLResponse {
print("Response: \(httpResponse.statusCode)")
} else { print("Response: No Response") }
}.resume()
}
Debug Console Output: