Tengo un punto final de descanso simple construido en PHP que funciona en cartero y navegadores.
https://someserver.com/api/endpoint.php?name=helloPero el código no se ejecuta cuando se invoca desde Swift. Tras la investigación, descubrí que Postman and Browser envía el encabezado de host mientras que Swift URLRequest no lo hace. Cuando no envía el encabezado HOST, el servidor php se niega a aceptar la solicitud entrante y creo que la solicitud se rechaza a nivel del servidor web. Intenté usar el
request.addValue("127.0.0.1", "Host")pero aun así no funcionó. Cualquier ayuda es apreciada.
Código completo (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) } })Swift está ignorando el hecho de que configuraste el encabezado, como debería ser. Consulte los documentos sobre los encabezados de Swift y por qué está ignorando su encabezado de Host .
The URL Loading System handles various aspects of the HTTP protocol for you (HTTP 1.1 persistent connections, proxies, authentication, and so on). As part of this support, the URL Loading System takes responsibility for certain HTTP headers: Content-Length Authorization Connection Host Proxy-Authenticate Proxy-Authorization WWW-Authenticate If you set a value for one of these reserved headers, the system may ignore the value you set, or overwrite it with its own value, or simply not send it. Moreover, the exact behavior may change over time. To avoid confusing problems like this, do not set these headers directly.La documentación está aquí:
https://developer.apple.com/documentation/foundation/nsurlrequest#1776617
He visto esto antes con Java: hay una solución en Java según la biblioteca que esté usando, pero no sé nada de Swift.
Descubrí que el problema ocurre solo cuando accedes a un servidor php. El servidor web php busca algún encabezado y no puede encontrarlo cuando la llamada se realiza desde Swift. Incluso copié el código de trabajo de Postman y los resultados fueron los mismos.
La solución que elegí fue crear un servidor proxy usando la función de nube de firebase. El código Swift golpearía una función en la nube de Firebase que habla con php y envía la respuesta a Swift.