I have a simple rest endpoint built on PHP that works on postman and browsers.
https://someserver.com/api/endpoint.php?name=hello
But the code fails to execute when invoked from Swift.
Upon Investigation, I found out that Postman and Browser sends the Host Header whereas the Swift URLRequest doesn’t. When you don’t send the HOST Header, the php server refuses to accept the incoming request and I believe the request is rejected at the web server level. I tried using the
request.addValue("127.0.0.1", "Host")
but it still didn’t work. Any help is appreciated.
Full Code (Swift 4)
let url = urlInput.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
print("URL is: " + url)
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = "GET"
request.addValue(<#T##value: String##String#>, forHTTPHeaderField: <#T##String#>)
let session = URLSession.shared
let task = session.dataTask(with: request, completionHandler: { data, response, error -> Void in
if let httpResponse = response as? HTTPURLResponse {
let respStr = String(data: data!, encoding: String.Encoding.utf8) as String?
print ("Response is (respStr ?? "")")
print("statusCode: (httpResponse.statusCode)")
let data: Data? = respStr?.data(using: .utf8)
}
})
2
Answers
I figured out that the issue happens only when you hit a php server. The php web server looks for some header and cant find it when the call is made from Swift. I even copied the working code from Postman and results were the same.
The solution I went with was to create a proxy server using firebase cloud function. Swift code would hit a firebase cloud function which talks to php and sends the response to swift.
Swift is ignoring the fact that you set the header, as it typically should. See the docs about Swift headers and why it’s ignoring your
Host
header.The documentation is here:
https://developer.apple.com/documentation/foundation/nsurlrequest#1776617
I have seen this before with Java – there is a workaround in Java depending on the library you are using, but I don’t know about Swift.