Изменяемый NSHTTPURLResponse или NSURLResponse

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


person Arlen Anderson    schedule 19.01.2010    source источник
comment
Вы пытаетесь изменить заголовки, получаемые с сервера ?! Вы имеете в виду NSURLRequest?   -  person notnoop    schedule 19.01.2010
comment
подожди ... нет ... я имею в виду NSURLResponse   -  person Arlen Anderson    schedule 19.01.2010


Ответы (4)


Я только что говорил об этом с другом. Я предлагаю написать подкласс 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.

person Colin Barrett    schedule 03.02.2010

Вы можете прочитать их в NSDictionary с помощью метода allHeaderFields.

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

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

if ([response respondsToSelector:@selector(allHeaderFields)]) {... }
person shawnwall    schedule 19.01.2010
comment
Разве это не возвращает NSDictionary вместо NSMutableDictionary? - person Arlen Anderson; 19.01.2010
comment
Да, это то, что есть в примере кода. Вот ссылка на класс developer.apple.com/iphone/library/documentation/Cocoa/ - person shawnwall; 19.01.2010
comment
Я не понимаю, как неизменяемый словарь поможет мне изменить ключи / значения - person Arlen Anderson; 19.01.2010
comment
Ах ... извините, моя ошибка - что именно вы пытаетесь сделать, изменяя ответ? Вы можете создать новый NSMutableDictionary и использовать setDictionary для помещения значений из исходных заголовков ответов, но я все еще не понимаю конечную цель здесь. - person shawnwall; 20.01.2010
comment
Используйте NSMutableDictionary * httpResponseHeaderFields = [[httpResponse allHeaderFields] mutableCopy]; Но на самом деле мы все могли бы помочь вам гораздо больше, если бы вы сказали нам, ПОЧЕМУ вы хотите изменить поля в ответе ... вы хотите обмануть какую-то библиотеку, возвращающую NSHTTPURLResponse? - person Kendall Helmstetter Gelner; 20.01.2010

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

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

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

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

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

которого нет в документации (ошибка документации), но есть в общедоступном API NSHTTPURLResponse

person Plamen Terziev    schedule 10.02.2012

Вы можете это сделать, и вам понадобится 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()
person William Kinaan    schedule 25.05.2016
comment
Ваш код управляет копией allHeaderFields. Он не редактирует заголовок внутри NSHTTPResponse - person Huy Le; 21.11.2018