【问题标题】:Mutable NSHTTPURLResponse or NSURLResponse可变的 NSHTTPURLResponse 或 NSURLResponse
【发布时间】:2010-01-19 20:01:02
【问题描述】:

我需要修改 NSURLResponse 中的响应标头。这可能吗?

【问题讨论】:

  • 您是否尝试修改从服务器获取的标头?!你是说 NSURLRequest 吗?
  • 等等……不……我的意思是 NSURLResponse

标签: nsurlconnection iphone nsurlrequest nsurlcache


【解决方案1】:

我刚刚和一个朋友谈论这个。我的建议是写一个 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 来调出课程。但是我不知道这是否会添加必要的实例变量。如果您可以支持足够新的 SDK,您也可以使用 objc_setAssociatedObject 并将其全部放入一个类别中。

【讨论】:

    【解决方案2】:

    您可以使用allHeaderFields 方法将它们读入NSDictionary。

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

    为了 100% 安全,您需要将其包裹起来

    if ([response respondsToSelector:@selector(allHeaderFields)]) {... }
    

    【讨论】:

    • 那不是返回 NSDictionary 而不是 NSMutableDictionary?
    • 是的,这就是代码示例中的内容。这是类参考developer.apple.com/iphone/library/documentation/Cocoa/…
    • 我看不出不可变字典将如何帮助我修改键/值
    • 啊...抱歉,我的错误-您到底想通过修改响应来做什么?您可以创建一个新的 NSMutableDictionary 并使用 setDictionary 来放置原始响应标头中的值,但我仍然不明白这里的最终目标。
    • 使用 NSMutableDictionary *httpResponseHeaderFields = [[httpResponse allHeaderFields] mutableCopy];但是,如果您告诉我们为什么要修改响应中的字段,我们真的可以为您提供更多帮助……您是否正在寻找“愚弄”某种库来获取 NSHTTPURLResponse?
    【解决方案3】:

    我遇到了类似的问题。我想修改 http url 响应的头文件。我需要它是因为想向 UIWebView 提供缓存的 url 响应,并想欺骗 Web 视图,使响应没有过期(即我想更改标头的“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
    

    不在文档中(文档错误),但在 NSHTTPURLResponse 的公共 API 中

    【讨论】:

      【解决方案4】:

      你可以这样做,你需要NSHTTPURLResponse 而不是NSURLResponse,因为在 Swift 中,NSURLResponse 可以与许多协议一起使用,而不仅仅是http,例如ftp、@987654326 @,或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()
      

      【讨论】:

      • 您的代码操作了 allHeaderFields 的副本。它不会在 NSHTTPResponse 中编辑标头
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      • 2013-10-04
      • 1970-01-01
      • 2015-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多