11

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.

4

10 に答える 10

11

更新: これは既知の問題です。


allHeaderFieldsHTTP 仕様で要求されているため、大文字と小文字を区別しない辞書を返す必要があります。Swift のエラーのようです。レーダーまたはバグ レポートを に提出します。

問題を簡単に再現するサンプルコードを次に示します。

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)

( Cédric Luthi のこの Gist から適応。)

于 2016-10-20T11:06:20.240 に答える
5

より効率的な回避策:

(response.allHeaderFields as NSDictionary)["etag"]
于 2019-02-11T23:55:24.193 に答える
1

Swift 3 のホットフィックスとして、次のことができます。

// Converting to an array of tuples of type (String, String)
// The key is lowercased()
let keyValues = response.allHeaderFields.map { (String(describing: $0.key).lowercased(), String(describing: $0.value)) } 

// Now filter the array, searching for your header-key, also lowercased
if let myHeaderValue = keyValues.filter({ $0.0 == "X-MyHeaderKey".lowercased() }).first {
    print(myHeaderValue.1)
}

更新: この問題は、Swift 4 ではまだ修正されていないようです。

于 2017-01-02T15:08:39.630 に答える