WKWebView加载一个网页资源过多,加载速度过慢。可以将部分资源放在本地,拦截webview的链接和请求,本地有的资源直接获取本地的,不去加载网络服务器内容
首先自定义一个继承自NSURLProtocol的类
然后重写+ (BOOL)canInitWithRequest:(NSURLRequest *)request
重写
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request
- (void)startLoading、
然后需要在调用的webview控制器中实现注册
[NSURLProtocol registerClass:[NSURLProtocolCustom class]];
//实现拦截功能,这个是WKWebView的核心
Class cls = NSClassFromString(@"WKBrowsingContextController");
SEL sel = NSSelectorFromString(@"registerSchemeForCustomProtocol:");
if ([(id)cls respondsToSelector:sel]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[(id)cls performSelector:sel withObject:@"http"];
[(id)cls performSelector:sel withObject:@"https"];
#pragma clang diagnostic pop
}
上代码
#import "NSURLProtocolCustom.h"
#import <CoreFoundation/CoreFoundation.h>
#import <MobileCoreServices/MobileCoreServices.h>
@implementation NSURLProtocolCustom
+ (BOOL)canInitWithRequest:(NSURLRequest *)request{
NSString *urlPathString = request.URL.absoluteString;
NSLog(@"canInitWithRequest ------- %@",urlPathString);
urlPathString = [self RequestHeaderProtocolWithUrlabsoluteString:urlPathString];
if ([urlPathString containsString:@"png?"]) {
NSArray *urlPaths = [urlPathString componentsSeparatedByString:@".png?"];
urlPathString = [NSString stringWithFormat:@"%@.png",urlPaths[0]];
}
NSString *filePath = [[NSBundle mainBundle] pathForResource:urlPathString ofType:@""];
if ([NSData dataWithContentsOfFile:filePath]) {
return YES;
}
return NO;
}
///转换http和https协议头
+ (NSString *)RequestHeaderProtocolWithUrlabsoluteString:(NSString *)UrlString
{
if ([UrlString containsString:@"http://"] ) {
UrlString = [UrlString stringByReplacingOccurrencesOfString:@"http://" withString:@""];
}else if ([UrlString containsString:@"https://"]){
UrlString = [UrlString stringByReplacingOccurrencesOfString:@"https://" withString:@""];
}
return UrlString;
}
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request
{
NSLog(@"canonicalRequestForRequest");
return request;
}
- (void)startLoading{
NSLog(@"*****startLoading");
NSLog(@"%@", super.request.URL);
NSString *urlPathString = super.request.URL.absoluteString;
urlPathString = [NSURLProtocolCustom RequestHeaderProtocolWithUrlabsoluteString:urlPathString];
if ([urlPathString containsString:@"png?"]) {
NSArray *urlPaths = [urlPathString componentsSeparatedByString:@".png?"];
urlPathString = [NSString stringWithFormat:@"%@.png",urlPaths[0]];
}
NSString *filePath = [[NSBundle mainBundle] pathForResource:urlPathString ofType:@""];
NSData *imageData = [self DataWithPath:filePath];
if (imageData ) {
//获取本地资源成功
NSLog(@"*******--------%@",filePath);
CFStringRef pathExtension = (__bridge_retained CFStringRef)[filePath pathExtension];
CFStringRef type = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension, NULL);
CFRelease(pathExtension);
// The UTI can be converted to a mime type:
NSString *mimeType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass(type, kUTTagClassMIMEType);
NSMutableDictionary *header = [NSMutableDictionary dictionary];
NSString *contentType = [mimeType stringByAppendingString:@";chartset=UTF-8"];
header[@"Content-type"] = contentType;
header[@"Content-Length"] = [NSString stringWithFormat:@"%ld",imageData.length];
NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:self.request.URL
statusCode:200 HTTPVersion:@"1.1" headerFields:header];
//回调
[self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowed];
[self.client URLProtocol:self didLoadData:imageData];
[self.client URLProtocolDidFinishLoading:self];
}else{
//获取本地资源失败
[NSURLProtocol setProperty:@(YES) forKey:@"JXProtocol" inRequest:super.request];
NSMutableURLRequest *newRequset = [self.request mutableCopy];
NSURLSessionConfiguration *config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
NSURLSessionTask *task = [session dataTaskWithRequest:newRequset];
[task resume];
}
}
- (void)stopLoading{
NSLog(@"stop******");
}
- (NSData*)DataWithPath:(NSString*)filePath{
NSData *data = [NSData dataWithContentsOfFile:filePath];
if (data) {
return data;
}
return nil;
}
#pragma mark- NSURLConnectionDelegate
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[self.client URLProtocol:self didFailWithError:error];
}
#pragma mark - NSURLConnectionDataDelegate
- (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];
}
@end