详解如何拦截iOS所有网络请求

  


  

  

最近在研究<代码> iOS无埋点统计技术,我们的<代码>统计SDK代码> 方法纵酒实现的,可以做到使用中不需要一行代码实现统计所有事件,具体细节将来我会专门抽几篇文章介绍。

  

今天主要说说如何统计应用中的所有网络请求。公司网络请求如果不是<代码>静态库> 框架> NSURLProtocol>   


  

  

NSURLProtocol是iOS URL加载系统中的一部分,看起来像是一个协议,但其实这是一个类,而且必须使用该类的子类,并且需要被注册。先看看他在URL加载系统中的位置:

  

详解如何拦截iOS所有网络请求“> <br/>
  </p>
  <p> <br/>
  </p>
  <p>不管是UIWebView还是URLSession还是第三方的<代码> AFNetWorkong </代码>,<代码> Alamofire> </代码或者<代码> SDWebImage </代码>他们都是基于<代码> URLSession> </代码或者<代码> NSURLConnection> </代码来实现的,因此可以通过NSURLProtocol做自定义操作。</p>
  <ol>
  <李>重定向网络请求李</>
  <李>拦截网络加载,采用本地缓存李</>
  <李>修改请求信息李</>
  <李>自定义返回结果李</>
  <李>对请求进行HTTPDNS解析,动态设置主机,解决不同网络下客户端不能访问的情况李</>
  </ol>
  <p> <>强实现<br/>
  </强> </p>
  <p>首先要继承NSURLProtocol创建自定义的类,然后重写startload, stopLoading添加我们的统计代码就可以了:</p>
  
  <pre类=   静态NSString * const hasInitKey=@“LLMarkerProtocolKey”;   @ interface LLMarkerURLProtocol: NSURLProtocol   @end      

子类实现的NSURLProtocol方法:

  

1.0 <代码> + (BOOL) canInitWithRequest: (NSURLRequest *)请求>         + (BOOL) canInitWithRequest:请求(NSURLRequest *) {   如果([NSURLProtocol propertyForKey: hasInitKey inRequest:请求)){   返回NO;   }   返回YES;   }   之前      

2.0,<代码> + (NSURLRequest *) canonicalRequestForRequest: (NSURLRequest *)请求>         + (NSURLRequest *) canonicalRequestForRequest:请求(NSURLRequest *) {   返回请求;   }   之前      

3.0 <代码>,- (void) startload 开始网络请求,需要在该方法中发起一个请求,对于NSURLConnection来说,就是创建一个NSURLConnection,对于NSURLSession,就是发起一个NSURLSessionTask。一般下载前需要设置该请求正在进行下载,防止多次下载的情况发生。

        - (void) startload {   NSMutableURLRequest * mutableReqeust=[[自我要求]mutableCopy];//做下标记,防止递归调用   [NSURLProtocol setProperty: @YES forKey: hasInitKey inRequest: mutableReqeust);   自我。连接=(NSURLConnection connectionWithRequest: mutableReqeust委托:自我);   }   之前      

4.0, <代码> - - - - - - (void) stopLoading 停止相应请求,清空请求连接或任务。

        - (void) stopLoading {   (自我。连接取消);   }   之前      

5.0实现<代码> NSURLConnectionDelegate ,<代码> NSURLConnectionDataDelegate> NSURLSessionTaskDelegate>         # pragma马克- NSURLConnectionDelegate      - (void)连接:(NSURLConnection *)连接didFailWithError:错误(NSError *) {   (自我。客户端URLProtocol:自我didFailWithError:错误);   }   # pragma马克- NSURLConnectionDataDelegate   - (void)连接:(NSURLConnection *)连接didReceiveResponse: (NSURLResponse *)反应   {   自我。responseData=中[[NSMutableData alloc] init);   (自我。客户端URLProtocol:自我didReceiveResponse:响应cacheStoragePolicy: NSURLCacheStorageNotAllowed];   }      - (void)连接:连接(NSURLConnection *) didReceiveData:数据(NSData *) {   (自我。responseData方法中:数据);   (自我。客户端URLProtocol:自我didLoadData:数据);   }      - (void) connectionDidFinishLoading:连接(NSURLConnection *) {   (自我。客户端URLProtocolDidFinishLoading:自我);   }      

详解如何拦截iOS所有网络请求