19

Here's my naive first pass code:

var httpUrlResponse: NSHTTPURLResponse? // = (...get from server...)
let contentType = httpUrlResponse?.allHeaderFields["Content-Type"]

I've tried various derivations of this code, but I keep getting compiler warnings/errors related to the basic impedance mismatch between the NSDictionary type of the allHeaderFields property and my desire to just get a String or optional String.

Just not sure how to coerce the types.

Shruti Thombre
  • 989
  • 4
  • 11
  • 27
Daniel
  • 8,794
  • 4
  • 48
  • 71

5 Answers5

28

You can do something like the following in Swift 3:

if
    let httpResponse = response as? HTTPURLResponse, 
    let contentType = httpResponse.value(forHTTPHeaderField: "Content-Type") 
{
    // use contentType here
}
task.resume()

Obviously, here I'm going from the URLResponse (the response variable) to the HTTPURLResponse. And rather than fetching allHeaderFields, I’m using value(forHTTPHeaderField:) which is typed and uses case-insensitive keys.

Hopefully this illustrates the idea.

For Swift 2, see previous revision of this answer.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Why do you need to cast it to NSString before casting it to String? Wouldn't `as? String` work? – Aaron Brager Sep 01 '14 at 23:02
  • That double casting was an early Swift 2 problem, which is now rendered unnecessary. But the use of `value(forHTTPHeaderField:)`, shown in this revised answer, eliminates the `String` cast that `allHeaderFields` required, altogether. – Rob May 14 '22 at 17:54
1

This works with Xcode 6.1:

let contentType = httpUrlResponse?.allHeaderFields["Content-Type"] as String?

Multiple casts no longer required.

And in Xcode 6.3 with Swift 1.2, this works:

let contentType = httpUrlResponse?.allHeaderFields["Content-Type"] as? String
Daniel
  • 8,794
  • 4
  • 48
  • 71
1

I use an extension to URLResponse to simplify this one (Swift 3):

extension URLResponse {

    func getHeaderField(key: String) -> String? {
       if let httpResponse = self as? HTTPURLResponse {
           if let field = httpResponse.allHeaderFields[key] as? String {
                return field
            }
        }
        return nil
    }
}
eskimwier
  • 1,037
  • 13
  • 16
-2

Actually it should be as easy as this

NSString* contentType = [[(NSHTTPURLResponse*)theResponse allHeaderFields] valueForKey:@"content-type"];

or

NSString* contentType = [[(NSHTTPURLResponse*)theResponse allHeaderFields][@"content-type"]];

But the problem is that the response might return the name of the key as an upper case one or a lower case one, while NSDictionary is really case sensitive about keys, so you should do your own case insensitive search for the key

NSDictionary* allFields = [[(NSHTTPURLResponse*)theResponse allHeaderFields];
NSString* contentType;
for (NSString* key in allFields.allKeys) {
     if ([key compare:@"content-type" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
          // This is it
          contentType = allFields[key];
          break;
     }
 }
Boda
  • 1,484
  • 1
  • 14
  • 28
  • 1
    Answer requested for Swift language. Sorry, I thought tagging the question with Swift and including the Swift sample code would help. Also, I believe that the lookup is case-insensitive (per the documentation). – Daniel Sep 01 '14 at 20:23
  • 2
    HTTP header fields are case-insensitive, while the dictionary lookup is case-sensitive, but according to the `allHeaderFields` documentation, fortunately, "to simplify your code, certain header field names are canonicalized into their standard form". So you can lookup `Content-Type`. – Rob Sep 01 '14 at 22:49
  • 1
    @Daniel You should have tagged it on Swift only, there was an Objective-C tag on it! so anyway if you don't know how convert this to Swift, you are in a big trouble – Boda Sep 02 '14 at 09:36
  • @AubadaTaljo tagging this with objective-c as well is perfectly valid. The code they provided was with swift so you should have provided a swift answer, and the way this works is you don't tell them they are in big trouble if they can't convert it themselves if they knew how to do it they wouldn't be asking the question. Bad answer due to you not reading the question properly and then not providing what they wanted after clarification was made. And if you want to be critical looks like you don't know what your talking about in some of your answers. – Popeye Sep 04 '14 at 21:38