最近在公司做了一个混合开发的项目,有个需求是要加载本地的加密页面。所以就写了个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的请求剔除,所以出现了如果涉及到加载互联网网址的时候,有些网站会加载不正常,所以要注意。