iOS webview加载网页内容,拦截如果本地有资源就先加载本地资源

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

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值