Подтвердить что ты не робот

Как я могу получить доступ к заголовку "Content-Type" сообщения NSHTTPURLResponse?

Вот мой наивный код первого прохода:

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

Я пробовал различные определения этого кода, но я продолжаю получать предупреждения/ошибки компилятора, связанные с несоответствием основного импеданса между типом NSDictionary для свойства allHeaderFields и моим желанием просто получить String или необязательную строку.

Просто не уверен, как принудительно использовать типы.

4b9b3361

Ответ 1

В Swift 3 вы можете сделать что-то вроде следующего:

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()

Очевидно, здесь я перехожу от URLResponse (response) к HTTPURLResponse и получаю данные из allHeaderFields. Если у вас уже есть HTTPURLResponse, то это проще, но, надеюсь, это иллюстрирует идею.

Для Swift 2, см. предыдущую версию этого ответа.

Ответ 2

Это работает с Xcode 6.1:

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

Несколько отбросов больше не требуются.

И в Xcode 6.3 с Swift 1.2 это работает:

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

Ответ 4

Я использую расширение для URLResponse для упрощения этого (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
    }
}

Ответ 5

На самом деле это должно быть так же просто, как это

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

или

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

Но проблема в том, что ответ может вернуть имя ключа в виде верхнего или нижнего регистра, в то время как NSDictionary действительно чувствителен к регистру ключей, поэтому вы должны делать свой собственный регистр без учета поиска ключа

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