2014-09-01 2 views
13

Hier ist meine naive erste Pass-Code:Wie kann ich auf den Header "Content-Type" einer NSHTTPURLResponse zugreifen?

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

ich verschiedene Ableitungen dieses Codes habe versucht, aber ich halte Compiler-Warnungen bekommen/Fehler der Grund Impedance Mismatch zwischen der Art der Immobilie allHeaderFields NSDictionary bezogen und meine Wunsch, nur eine Zeichenfolge oder optionale Zeichenfolge zu erhalten.

Nur nicht sicher, wie man die Typen zwingt.

Antwort

21

Sie 3 in etwa wie folgt in Swift tun können:

let task = URLSession.shared.dataTask(with: url) { data, response, error in 
    if let httpResponse = response as? HTTPURLResponse, let contentType = httpResponse.allHeaderFields["Content-Type"] as? String { 
     // use contentType here 
    } 
} 
task.resume() 

Offensichtlich hier werde ich von der (die response Variable) zu HTTPURLResponse, und erhalten die Daten von allHeaderFields. Wenn Sie bereits die HTTPURLResponse haben, dann ist es einfacher, aber hoffentlich veranschaulicht dies die Idee.

Für Swift 2 siehe previous revision of this answer.

+0

Warum müssen Sie es in NSString konvertieren, bevor Sie es in String umwandeln? Wäre nicht 'wie? String' Arbeit? –

+2

@AaronBrager - BTW, die Dummheit von 'wenn contentType = ... wie? NSString als? String' wird nicht mehr benötigt. Ich habe es gerade in Xcode 6.3.1 getestet und die einfachere Umwandlung direkt in 'String' funktioniert nun einwandfrei. Ich habe daher diese frühere, schwerfällige Syntax aus meiner Antwort entfernt. – Rob

-2

Eigentlich sollte es so einfach sein wie das

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

oder

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

Aber das Problem ist, dass die Antwort könnte den Namen des Schlüssels als obere Fall ein oder Kleinschreibung zurückzukehren Eine, während NSDictionary wirklich Groß-und Kleinschreibung für Schlüssel, so sollten Sie Ihre eigenen Groß-und Kleinschreibung nicht nach dem Schlüssel

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; 
    } 
} 
+1

Antwort für Swift Sprache angefordert. Entschuldigung, ich dachte, die Frage mit Swift zu markieren, und der Swift-Beispielcode würde helfen. Ich glaube auch, dass bei der Suche die Groß-/Kleinschreibung nicht beachtet wird (laut Dokumentation). – Daniel

+2

HTTP-Header-Felder sind Groß-und Kleinschreibung, während die Wörterbuch-Lookup Groß-und Kleinschreibung, aber nach der "allHeaderFields" -Dokumentation, glücklicherweise ", um Ihren Code zu vereinfachen, sind bestimmte Header-Feldnamen in ihre Standardform kanonisiert". So können Sie nach 'Content-Type' suchen. – Rob

+1

@Daniel Du solltest es nur auf Swift getaggt haben, da war ein Objective-C-Tag drauf! Wenn Sie also nicht wissen, wie Sie dies in Swift konvertieren, sind Sie in großen Schwierigkeiten. –

1

Dies funktioniert mit Xcode 6.1:

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

Multiple wirft nicht mehr erforderlich.

Und in Xcode 6.3 mit Swift 1.2, das funktioniert:

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

Die zweite Anweisung funktioniert sogar vor 1.2, aber ich denke, es hat nicht im September? – Michal

0

Ich benutze eine Erweiterung URLResponse diese ein (Swift 3) zu vereinfachen:

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 
    } 
} 
Verwandte Themen