Converting to Swift 3 I noticed a strange bug occur reading a header field from HTTPURLResponse.
let id = httpResponse.allHeaderFields["eTag"] as? String
no longer worked.
I printed out the all headers dictionary and all my header keys seem to be in Sentence case.
According to Charles proxy all my headers are in lower case. According to the backend team, in their code the headers are in Title-Case. According the docs: headers should be case-insensitive.
So I don't know which to believe. Is anyone else finding in Swift 3 that their headers are now being turned into Sentence case by iOS? If so is this behaviour we want?
Should I log a bug with Apple or should I just make a category on HTTPURLResponse to allow myself to case insensitively find a header value.
More efficient workaround:
(response.allHeaderFields as NSDictionary)["etag"]
Due to a bug in Swift and a new solution in iOS 13, I made an extension:
Here is a link to gist.
public extension HTTPURLResponse {
func valueForHeaderField(_ headerField: String) -> String? {
if #available(iOS 13.0, *) {
return value(forHTTPHeaderField: headerField)
} else {
return (allHeaderFields as NSDictionary)[headerField] as? String
}
}
}
Update: this is a known issue.
allHeaderFields
should return a case-insensitive dictionary because that is what the HTTP spec requires. Looks like a Swift error, I would file a radar or a bug report on .
Here is some sample code that reproduces the issue simply:
let headerFields = ["ETag" : "12345678"]
let url = URL(string: "http://www.example.com")!
let response = HTTPURLResponse(url: url, statusCode: 200, httpVersion: "HTTP/1.1", headerFields: headerFields)!
response.allHeaderFields["eTaG"] // nil (incorrect)
headerFields["eTaG"] // nil (correct)
(Adapted from this Gist from Cédric Luthi.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With