[混合开发]使用NSURLProtocol子类加载本地加密页面文件

最近在公司做了一个混合开发的项目,有个需求是要加载本地的加密页面。所以就写了个NSURLProtocol的子类去拦截UIWebView的所有页面请求,再将本地的加密的页面解密后返回。

注册自定义的NSURLProtocol

[NSURLProtocol registerClass:[MyURLProtocaol class]]

先定义一个全局变量

static NSString * const URLProtocolHandledKey = @"URLProtocolHandledKey";

然后就可以实现几个方法

  • +canInitWithRequest:

    + (BOOL)canInitWithRequest:(NSURLRequest *)request{
      
      NSString *url = request.URL.absoluteString;
      
      // 如果url以https或http开头,则不拦截处理
      if ([url hasPrefix:@"https"] || [url hasPrefix:@"http"]) {
          return NO;
      }
      
      //看看是否已经处理过了,防止无限循环
      if ([NSURLProtocol propertyForKey:URLProtocolHandledKey inRequest:request]) {
          return NO;
      }
      
      return YES;
      }
    
  • -startLoading

    - (void)startLoading{
    
    NSMutableURLRequest *mutableReqeust = [[self request] mutableCopy];
    //打标签,防止无限循环
    [NSURLProtocol setProperty:@YES forKey:URLProtocolHandledKey inRequest:mutableReqeust];
    
    NSString *requestStr = [mutableReqeust.URL absoluteString];
    
    //多加一层判断,只处理加载本地文件的请求
    if (![requestStr hasPrefix:@"file:"]) {
        
        self.connection = [NSURLConnection connectionWithRequest:mutableReqeust delegate:self];
        return;
    }
    
    //对拦截的请求进行处理
    NSData *de_data = [[NSData dataWithContentsOfURL:mutableReqeust.URL] AES128DecryptWithKey:@"Ctl62fuMCkfSPl/+" iv:@"0000000000123456"];
    
    NSURLResponse *response = [[NSURLResponse alloc] initWithURL:[self.request URL] MIMEType:@"application/octet-stream" expectedContentLength:-1 textEncodingName:nil];
    [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
    [self.client URLProtocol:self didLoadData:de_data];
    [self.client URLProtocolDidFinishLoading:self];
    
    self.connection = [NSURLConnection connectionWithRequest:mutableReqeust delegate:self];
    

}


###最主要就是以上两个方法,其它的方法如下
  • (NSURLRequest *) canonicalRequestForRequest:(NSURLRequest *)request {

    return request;
    }

  • (BOOL)requestIsCacheEquivalent:(NSURLRequest *)a toRequest:(NSURLRequest *)b{

    return [super requestIsCacheEquivalent:a toRequest:b];
    }

  • (void)stopLoading{

    [self.connection cancel];
    }

pragma mark - NSURLConnectionDelegate

  • (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {

    [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
    }

  • (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

    [self.client URLProtocol:self didLoadData:data];
    }

  • (void) connectionDidFinishLoading:(NSURLConnection *)connection {

    [self.client URLProtocolDidFinishLoading:self];
    }

  • (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {

    [self.client URLProtocol:self didFailWithError:error];
    }


>刚刚开始的时候没有注意,没有把http和https的请求剔除,所以出现了如果涉及到加载互联网网址的时候,有些网站会加载不正常,所以要注意。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容