iOS webView 远端h5优先加载本地资源

前言:UIWebView调用远端h5页面,优先加载本地图片、js、css等资源,解决办法就是对请求进行拦截。

服务端代码放在本文后面

客户端需要对NSURLProtocol 的自定义类进行注册,那么所有的webview 对http请求都会被他拦截到;

首先自定义NSURLProtocol类

#import <Foundation/Foundation.h>
#import <CoreFoundation/CoreFoundation.h>
#import <MobileCoreServices/MobileCoreServices.h>

@interface NSURLProtocolCustom : NSURLProtocol

@end
#import "NSURLProtocolCustom.h"

static NSString* const FilteredKey = @"FilteredKey";

@implementation NSURLProtocolCustom

+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
    NSString *extension = request.URL.pathExtension;
    BOOL isSource = [@[@"png", @"jpeg", @"gif", @"jpg", @"js", @"css"] indexOfObjectPassingTest:^BOOL(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        return [extension compare:obj options:NSCaseInsensitiveSearch] == NSOrderedSame;
    }] != NSNotFound;
    return [NSURLProtocol propertyForKey:FilteredKey inRequest:request] == nil && isSource;
}

+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request
{
    return request;
}

- (void)startLoading
{
    NSString *fileName = [super.request.URL.absoluteString componentsSeparatedByString:@"/"].lastObject;
    NSLog(@"fileName is %@",fileName);
    //这里是获取本地资源路径 如:png,js等
    NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:nil];
    if (!path) {
        [self sendResponseWithData:[NSData data] mimeType:nil];
        return;
    }
    
    //根据路径获取MIMEType
    CFStringRef pathExtension = (__bridge_retained CFStringRef)[path 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);
    if (type != NULL)
        CFRelease(type);
    
    //加载本地资源
    NSData *data = [NSData dataWithContentsOfFile:path];
    [self sendResponseWithData:data mimeType:mimeType];
}

- (void)stopLoading
{
    NSLog(@"stopLoading, something went wrong!"); 
}

- (void)sendResponseWithData:(NSData *)data mimeType:(nullable NSString *)mimeType
{
    // 这里需要用到MIMEType
    NSURLResponse *response = [[NSURLResponse alloc] initWithURL:super.request.URL
                                                        MIMEType:mimeType
                                           expectedContentLength:-1
                                                textEncodingName:nil];
    
    //硬编码 开始嵌入本地资源到web中
    [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
    [[self client] URLProtocol:self didLoadData:data];
    [[self client] URLProtocolDidFinishLoading:self];
}

@end

其次实现对类的注册

#import "CWWebView.h"
#import "NSURLProtocolCustom.h"

@interface CWWebView ()<UIWebViewDelegate>

@property (nonatomic,strong) UIWebView *myWebView;

@end

@implementation CWWebView

- (void)viewDidLoad {
    [super viewDidLoad];
    //1.注册自定义类
    [NSURLProtocol registerClass:[NSURLProtocolCustom class]];
    //2.添加
    [self.view addSubview:self.myWebView];
}

- (UIWebView *)myWebView
{
    if (!_myWebView) {
        _myWebView = [[UIWebView alloc] initWithFrame:self.view.bounds];
        _myWebView.backgroundColor = [UIColor redColor];
        _myWebView.scalesPageToFit = YES;
        _myWebView.delegate = self;
        NSURL *url = [[NSURL alloc] initWithString:@"http://139.224.57.105/apptest/app.html"];
        NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
        [_myWebView loadRequest:request];
    }
    return _myWebView;
}

@end

服务端代码

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>测试iOS与JS之间的互调</title>
    <style type="text/css">
        {
            font-size: 40px;
        }
    </style>
</head>
<body>
<div style="rargin-top: 100px;">
    <h1>Test how to use Objective-C call js</h1>
    <input type="button" value="Call iOS" οnclick="calliOS('call iOS')">
    <input type="button" value="Call JS Alert" οnclick="jsFunc()">
</div>
<div>
    <input type="button" value="iOS Call With No JSON" οnclick="callJS()">
    <input type="button" value="iOS Call With JSON" οnclick="callJSMsg('iOS Call JS')">
</div>
<div>
    <span id="jsParatFuncSpan" style="color:red; font-size:50px;"></span>
</div>
</body>
<script type="text/JavaScript" src="appJs.js"></script>
</html>


本地js文件

function calliOS(Msg) {
    var message = {
        'method' : 'hello',
        'param1' : Msg,
    };
    window.webkit.messageHandlers.webViewApp.postMessage(message);
}

function callJS() {
    var message = {
        'method' : 'Call JS',
    };
    window.webkit.messageHandlers.webViewApp.postMessage(message);
}

function callJSMsg(Msg) {
    var message = {
        'method' : 'Call JS Msg',
        'param1' : Msg,
    };
    window.webkit.messageHandlers.webViewApp.postMessage(message);
}

function jsFunc() {
    alert('Hello World');
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值