{"id":28551,"date":"2020-04-03T16:48:16","date_gmt":"2020-04-03T20:48:16","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=28551"},"modified":"2020-04-03T16:51:23","modified_gmt":"2020-04-03T20:51:23","slug":"swift-bridging-of-allheaderfields","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2020\/04\/03\/swift-bridging-of-allheaderfields\/","title":{"rendered":"Swift Bridging of allHeaderFields"},"content":{"rendered":"<p><a href=\"https:\/\/twitter.com\/0xced\/status\/1246067471863275520\">C&eacute;dric Luthi<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/0xced\/status\/1246067471863275520\">\n<p>I don&rsquo;t do a lot of swift. But every time I do, I stumble on obscure quirks. Last case in point: <code>HTTPURLResponse<\/code> <code>allHeaderFields<\/code> is <a href=\"https:\/\/bugs.swift.org\/browse\/SR-2429\">now case-sensitive<\/a>.<\/p>\n<\/blockquote>\n<p>This seems to be because the property is implemented using an <code>NSDictionary<\/code> subclass. <a href=\"https:\/\/developer.apple.com\/documentation\/foundation\/nshttpurlresponse\/1417930-allheaderfields?language=objc\">Apple<\/a> notes:<\/p>\n<blockquote cite=\"https:\/\/developer.apple.com\/documentation\/foundation\/nshttpurlresponse\/1417930-allheaderfields?language=objc\">\n<p>In Objective-C, the returned dictionary of headers is case-preserving during the set operation (unless the key already exists with a different case), and case-insensitive when looking up keys.<\/p>\n<\/blockquote>\n<p>But Swift bridging converts it to a regular Swift <code>Dictionary<\/code>, which is case-sensitive (though looser about Unicode).<\/p>\n<p>In general, you can avoid the bridging by casting:<\/p>\n<pre>allHeaderFields as NSDictionary<\/pre>\n<p>In this particular case, there is an <a href=\"https:\/\/developer.apple.com\/documentation\/foundation\/httpurlresponse\/3240613-value\">extra API<\/a> in Catalina and iOS 13 to look up header fields in a case-insensitive way:<\/p>\n<pre>func value(forHTTPHeaderField field: String) -&gt; String?<\/pre>\n<p>This is an interesting case study of the current Cocoa documentation because:<\/p>\n<ul>\n<li><p>The discussion of <code>allHeaderFields<\/code> on the Web has language-specific notes that disappear depending on whether you&rsquo;ve selected Objective-C or Swift. With <a href=\"https:\/\/developer.apple.com\/documentation\/foundation\/httpurlresponse\/1417930-allheaderfields\">Swift selected<\/a>, it helpfully says:<\/p>\n<blockquote cite=\"https:\/\/developer.apple.com\/documentation\/foundation\/httpurlresponse\/1417930-allheaderfields\"><p>Because this property is a standard Swift dictionary, its keys are case-sensitive. To perform a case-insensitive header lookup, use the <code>value(forHTTPHeaderField:)<\/code> method instead.<\/p><\/blockquote>\n<\/li>\n<li><p>The text in Xcode 11.3 and Dash is different still:<\/p>\n<blockquote><p>The returned dictionary of headers is configured to be case-preserving during the set operation (unless the key already exists with a different case), and case-insensitive when looking up keys.<\/p><\/blockquote><\/li>\n<\/ul>\n<p>I would rather have a single version of the documentation that includes all the information, with the only difference being the syntax used. Otherwise, I have to switch back and forth to make sure I&rsquo;m not missing anything.<\/p>\n\n<p>Previously:<\/p>\n<ul>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2019\/03\/14\/netservice-nuthouse\/\">NetService NutHouse<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2019\/02\/22\/swift-subclass-of-nstextstorage-is-slow-because-of-swift-bridging\/\">Swift Subclass of NSTextStorage Is Slow Because of Swift Bridging<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2017\/12\/05\/key-difference-between-dictionary-and-nsdictionary\/\">Key Difference Between Dictionary and NSDictionary<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2017\/08\/29\/swift-4-bridging-peephole-for-as-casts\/\">Swift 4: Bridging Peephole for &ldquo;as&rdquo; Casts<\/a><\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>C&eacute;dric Luthi: I don&rsquo;t do a lot of swift. But every time I do, I stumble on obscure quirks. Last case in point: HTTPURLResponse allHeaderFields is now case-sensitive. This seems to be because the property is implemented using an NSDictionary subclass. Apple notes: In Objective-C, the returned dictionary of headers is case-preserving during the set [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"2020-04-03T20:48:20Z","apple_news_api_id":"771a547a-b967-4611-9967-aae9955d2585","apple_news_api_modified_at":"2020-04-03T20:51:26Z","apple_news_api_revision":"AAAAAAAAAAAAAAAAAAAAAw==","apple_news_api_share_url":"https:\/\/apple.news\/AdxpUerlnRhGZZ6rplV0lhQ","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[69,231,164,31,1667,30,1666,71,901],"class_list":["post-28551","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-cocoa","tag-dash","tag-documentation","tag-ios","tag-ios-13","tag-mac","tag-macos-10-15","tag-programming","tag-swift-programming-language"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/28551","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=28551"}],"version-history":[{"count":4,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/28551\/revisions"}],"predecessor-version":[{"id":28557,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/28551\/revisions\/28557"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=28551"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=28551"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=28551"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}