zoukankan      html  css  js  c++  java
  • iOS中的中间人-NSURLProtocol 的原理和使用实例

    Part 1: 使用范围

    • 能拦截NSURLRequest请求

    When an
    NSURLSession, NSURLConnection, or NSURLDownload object initiates a connection for an NSURLRequest
    object, the URL loading system consults each of the registered NSURLProtocol classes in the reverse order of their registration

    • 通过CFNetwork层CFHTTPMessageCreateRequest是无法拦截的

    Part 2: 作用机制

    The URL loading system is responsible for creating and releasing NSURLProtocol instances when connections start and complete. Your app should never create an instance of NSURLProtocol directly.
    When an NSURLProtocol subclass is initialized by the URL loading system, it is provided a client object that conforms to the NSURLProtocolClient protocol. The NSURLProtocol subclass sends messages from the NSURLProtocolClient protocol to the client object to inform the URL loading system of its actions as it
    creates a response, receives data, redirects to a new URL, requires authentication, and completes the load.
    If the custom protocol supports authentication, then it must conform to the
    NSURLAuthenticationChallengeSender protocol.

    Part 3: 使用姿势

    URL Loading system会在合适的时机,调用NSURLProtocol subclass中的以下方法:

    • -initWithRequest:cachedResponse:client:
    • -startLoading
      子类应该在此方法中,通过某种方式开始加载
    • -stopLoading
      子类应该在此方法中停止加载
    • -dealloc

    子类在加载过程中,应该在合适的时机调用NSURLProtocolClient中的以下方法:

    • -URLProtocol:didReceiveResponse:cacheStoragePolicy: //收到了响应头时调用
    • -URLProtocol:didLoadData: //收到了响应数据时调用
    • -URLProtocolDidFinishLoading:或者 -URLProtocol: didFailWithError: //加载完成或者失败时调用

    如果加载过程中有跳转,则应该直接调用以下方法:

    • -URLProtocol: wasRedirectedToRequest: redirectResponse:

    2015.10.26更新:跟同事讨论时谈到了既然子类已经控制了加载的过程,为什么还要调用client的一些里的方法?结论是需要通知到URL loading system,上层的一系列关于网络请求状态的delegate方法(比如UIWebview)才能被调用。

    Part 4: 实例

    我写的两个NSURLProtocol子类,分别用NSURLConnection和ASI实现的,放在了github上:https://github.com/grittymindy/NSURLProtocolDemo

  • 相关阅读:
    freebsd安装mysql
    freebsd安装ports
    分布式拒绝服务攻击
    如何用命令获知当前是一年中的第多少周和今天是周几
    freebsd软件包下载地址
    mod_wsgi的两种模式
    freebsd中/etc/rc.conf配置文件导致不能启动的问题
    进程ID[PID(Process ID)]与端口号[(Port ID)]的联系
    Java EE之HttpServletRequest
    Chrome之控制台使用【转载】
  • 原文地址:https://www.cnblogs.com/mindyme/p/4898224.html
Copyright © 2011-2022 走看看