2014-09-01 13 views
13

Dưới đây là ngây thơ đầu tiên mật mã của tôi:Tôi làm cách nào để truy cập tiêu đề "Loại nội dung" của NSHTTPURLResponse?

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

Tôi đã thử Mục từ khác nhau của mã này, nhưng tôi cứ bị cảnh báo trình biên dịch/lỗi liên quan đến việc không phù hợp trở kháng cơ bản giữa các loại NSDictionary tài sản allHeaderFields và tôi mong muốn chỉ nhận được Chuỗi hoặc Chuỗi tùy chọn.

Chỉ cần không chắc chắn cách ép buộc các loại.

Trả lời

21

Bạn có thể làm một cái gì đó như sau trong 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() 

Rõ ràng, ở đây tôi sẽ từ (biến số response) đến số HTTPURLResponse và nhận dữ liệu từ allHeaderFields. Nếu bạn đã có HTTPURLResponse, thì nó đơn giản hơn, nhưng hy vọng điều này minh họa ý tưởng.

Đối với Swift 2, xem previous revision of this answer.

+0

Tại sao bạn cần truyền nó sang NSString trước khi truyền nó vào String? Sẽ không 'như? String' hoạt động? –

+2

@AaronBrager - BTW, sự silliness của 'if let contentType = ... as? NSString như? Chuỗi' không còn cần thiết nữa. Tôi vừa thử nghiệm nó trong Xcode 6.3.1 và việc cast đơn giản trực tiếp vào 'String' bây giờ hoạt động tốt. Do đó tôi đã loại bỏ cú pháp cũ, cồng kềnh đó khỏi câu trả lời của tôi. – Rob

-2

Trên thực tế nó nên càng dễ dàng như thế này

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

hoặc

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

Nhưng vấn đề là các phản ứng có thể quay trở lại tên của khóa như một chữ hoa một hoặc một chữ thường một, trong khi NSDictionary thực sự là trường hợp nhạy cảm về khóa, vì vậy bạn nên thực hiện tìm kiếm phân biệt chữ hoa chữ thường cho khóa

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

trả lời yêu cầu cho ngôn ngữ Swift. Xin lỗi, tôi nghĩ việc gắn thẻ câu hỏi với Swift và bao gồm mã mẫu Swift sẽ giúp ích. Ngoài ra, tôi tin rằng tra cứu không phân biệt chữ hoa chữ thường (theo tài liệu). – Daniel

+2

Trường tiêu đề HTTP phân biệt chữ hoa chữ thường, trong khi tra cứu từ điển phân biệt chữ hoa chữ thường, nhưng theo tài liệu 'allHeaderFields', may mắn thay," để đơn giản hóa mã của bạn, một số tên trường tiêu đề được chuẩn hóa thành dạng chuẩn ". Vì vậy, bạn có thể tra cứu 'Content-Type'. – Rob

+1

@Daniel Bạn nên gắn thẻ nó trên Swift chỉ, có một thẻ Objective-C trên đó! vì vậy dù sao nếu bạn không biết cách chuyển đổi thành Swift, bạn gặp rắc rối lớn –

1

Điều này hoạt động với Xcode 6.1:

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

Nhiều phôi không còn cần thiết nữa.

Và trong Xcode 6.3 với Swift 1.2, công trình này:

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

Câu lệnh thứ hai hoạt động ngay cả trước 1.2, nhưng tôi đoán nó không có trong tháng 9? – Michal

0

tôi sử dụng một phần mở rộng để URLResponse để đơn giản hóa này (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 
    } 
} 
Các vấn đề liên quan