Изменяемый NSHTTPURLResponse или NSURLResponse - PullRequest
3 голосов
/ 19 января 2010

Мне нужно изменить заголовки ответа в NSURLResponse.Возможно ли это?

Ответы [ 4 ]

9 голосов
/ 03 февраля 2010

Я только что говорил об этом с другом.Мое предложение было бы написать подкласс NSURLResponse.Что-то вроде этого:

@interface MyHTTPURLResponse : NSURLResponse { NSDictionary *myDict; } 
- (void)setAllHeaderFields:(NSDictionary *)dictionary;
@end

@implementation MyHTTPURLResponse
- (NSDictionary *)allHeaderFields { return myDict ?: [super allHeaderFields]; }
- (void)setAllHeaderFields:(NSDictionary *)dict  { if (myDict != dict) { [myDict release]; myDict = [dict retain]; } }
@end

Если вы имеете дело с объектом, который вы не сделали, вы можете попробовать использовать object_setClass, чтобы раскрутить класс.Однако я не знаю, добавит ли это необходимую переменную экземпляра.Вы также можете использовать objc_setAssociatedObject и поместить все это в категорию, если вы можете поддерживать достаточно новый SDK.

3 голосов
/ 19 января 2010

Вы можете прочитать их в NSDictionary, используя метод allHeaderFields.

    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
    NSDictionary *httpResponseHeaderFields = [httpResponse
allHeaderFields];

Чтобы быть на 100% безопасным, вам нужно обернуть его

if ([response respondsToSelector:@selector(allHeaderFields)]) {... }
1 голос
/ 10 февраля 2012

У меня была похожая проблема.Я хотел изменить заголовочные поля http-ответа.Я нуждался в этом, потому что хотел предоставить кэшированный URL-ответ для UIWebView и хотел обмануть веб-представление тем, что срок ответа не истек (то есть я хотел изменить свойство заголовка «Cache-Control», но оставить остальные заголовки).Мое решение состояло в том, чтобы использовать NSKeyedArchiver для кодирования исходного ответа http и перехватывать сериализацию с делегатом.В

-(id) archiver:(NSKeyedArchiver*) archiver willEncodeObject:(id) object

я проверяю, является ли объект NSDictionary, и если да, я возвращал измененный словарь (то есть с обновленным заголовком «Cache-Control»).После этого я просто десериализовал сериализованный ответ, используя NSKeyedUnarchiver.Конечно, вы можете подключиться к unarchiver и изменить заголовки в его делегате.

Обратите внимание, что в iOS 5 Apple добавила

-(id)initWithURL:(NSURL*) url statusCode:(NSInteger) statusCode HTTPVersion:(NSString*) HTTPVersion headerFields:(NSDictionary*) headerFields

, которого нет в документации (ошибка документации),но это в публичном API NSHTTPURLResponse

0 голосов
/ 25 мая 2016

Вы можете сделать это, и вам понадобится NSHTTPURLResponse, а не NSURLResponse, потому что в Swift NSURLResponse может использоваться со многими протоколами, а не просто http, такими как ftp, data: или https. В результате вы можете вызвать его, чтобы получить метаданные, такие как ожидаемый тип контента, тип mime и кодировка текста, тогда как NSHTTURLResponse отвечает за обработку ответов протокола HTTP. Таким образом, именно он манипулирует заголовками.

Это небольшой код, который манипулирует ключом заголовка Server из ответа и печатает значение до и после изменения.

let url = "https://www.google.com"
    let request = NSMutableURLRequest(URL: NSURL(string: url)!)
    let session = NSURLSession.sharedSession()
    let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in

        if let response = response {

            let nsHTTPURLResponse = response as! NSHTTPURLResponse
            var headers = nsHTTPURLResponse.allHeaderFields
            print ("The value of the Server header before is: \(headers["Server"]!)")
            headers["Server"] = "whatever goes here"
            print ("The value of the Server header after is: \(headers["Server"]!)")

        }

        })
        task.resume()
...