本文是通过
WKURLSchemeHandler
的方式实现的请求拦截,
WKWebView
的
WKURLSchemeHandler
是不支持拦截
http/https/file
等原始协议的,如果通过
[config setURLSchemeHandler:handler forURLScheme:@"http"];
就会闪退,但是支持自定义协议,但是有时候项目就是需要拦截这些请求,该怎么处理呢?
一、自定义一个
HFURLSchemeHandler
类,并实现
WKURLSchemeHandler
代理
1、HFURLSchemeHandler.h文件实现,遵循
<WKURLSchemeHandler>
代理
#import <Foundation/Foundation.h>
#import <WebKit/WebKit.h>
@interface HFURLSchemeHandler : NSObject <WKURLSchemeHandler>
2、HFURLSchemeHandler.m文件实现两个代理方法- (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)urlSchemeTask
和- (void)webView:(WKWebView *)webView stopURLSchemeTask:(id<WKURLSchemeTask>)urlSchemeTask
#import "HFURLSchemeHandler.h"
@implementation HFURLSchemeHandler
- (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)urlSchemeTask{
NSURLRequest *request = urlSchemeTask.request;
NSString *urlStr = request.URL.absoluteString;
if ([urlStr hasPrefix:@"file://"]) {
// scheme切换回本地文件协议file://
NSURLRequest *fileUrlRequest = [[NSURLRequest alloc] initWithURL:request.URL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:0];
// 异步加载本地资源
NSURLSession *session = [NSURLSession sharedSession];
// 请求加载任务
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:fileUrlRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error) {
[urlSchemeTask didFailWithError:error];
} else {
NSDictionary *headerFields = @{
@"Content-Type":[NSString stringNullDealWith:response.MIMEType],
@"Content-Length":[NSString stringWithFormat:@"%ld", data.length]
response = [[NSHTTPURLResponse alloc] initWithURL:request.URL statusCode:200 HTTPVersion:@"HTTP/1.1" headerFields:headerFields];
// 将数据回传给webView
[urlSchemeTask didReceiveResponse:response];
[urlSchemeTask didReceiveData:data];
[urlSchemeTask didFinish];
[dataTask resume];
- (void)webView:(WKWebView *)webView stopURLSchemeTask:(id<WKURLSchemeTask>)urlSchemeTask {
NSLog(@"stop = %@",urlSchemeTask);
[urlSchemeTask didFinish];
二、在WKWebView中配置需要拦截的协议名称
如果setURLSchemeHandler: forURLScheme:
中的URLScheme
设置的是http/https/file
,会出现崩溃,但是可设置自定义的URLScheme
,例如:@"Customer"
;如果要实现对http/https/file
的拦截,请查看第三步。
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
// 配置请求拦截(根据协议拦截)
HFURLSchemeHandler *handler = [HFURLSchemeHandler new];
[config setURLSchemeHandler:handler forURLScheme:@"file"];
三、配置允许拦截http/https/file
实现这个需求,则需要借助runtime
的知识,方法替换method_exchangeImplementations
,将WKWebView
中的handlesURLScheme
方法替换成自定义的方法。
给WKWebView增加一个分类,取名为WKWebView+SchemeHandle
。
1、WKWebView+SchemeHandle.h
#import <WebKit/WebKit.h>
@interface WKWebView (SchemeHandle)
2、WKWebView+SchemeHandle.m 重写+ (void)load
方法进行方法替换
#import "WKWebView+SchemeHandle.h"
#import <objc/runtime.h>
@implementation WKWebView (SchemeHandle)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Method originalMethod1 = class_getClassMethod(self, @selector(handlesURLScheme:));
Method swizzledMethod1 = class_getClassMethod(self, @selector(yyhandlesURLScheme:));
method_exchangeImplementations(originalMethod1, swizzledMethod1);
+ (BOOL)yyhandlesURLScheme:(NSString *)urlScheme {
if ([urlScheme isEqualToString:@"http"] || [urlScheme isEqualToString:@"https"] || [urlScheme isEqualToString:@"file"]) {
return NO; //这里让返回NO,应该是默认不走系统断言或者其他判断啥的
} else {
return [self handlesURLScheme:urlScheme];
至此,就可以实现WKWebView的请求拦截了。
本文是通过WKURLSchemeHandler的方式实现的请求拦截,WKWebView的WKURLSchemeHandler是不支持拦截http/https/file等原始协议的,如果通过[config setURLSchemeHandler:handler forURLScheme:@"http"];就会闪退,但是支持自定义协议,但是有时候项目就是需要拦截这些请求,该怎么处理呢?一、自定义一个HFURLSchemeHandler类,并实现WKURLSchemeHandler代理1、HFURLSch
项目地址github:<a href="https://github.com/LiuShuoyu/HybirdWKWebVIew/">HybirdWKWebVIew</a>
HybridNSURLProtocol
一个基于WKWebView的hybirde的容器。能拦截所有WKWKWebView的的css,js,png等网络请求的demoNSURLProtoco...
使用WKWebURLSchemeHandler
iOS11以上,苹果为WKWebView增加了WKURLSchemeHandler协议,可以为自定义的Scheme增加遵循WKURLSchemeHandler协议的处理。其中可以在start和stop的时机增加自己的处理。
遵循协议中的两个方法
funcwebView(_webView:WKWebView,starturlSchem...
由于在项目中展示https网页的时候,WKWebView中某些网址打不开,用谷歌浏览器打开发现是:服务器证书无效,其实就是网站不受信任。
1、 配置info.pist
首先确定 App Transport Security Settings是否添加,App Transport Security Settings下添加Allow Arbitrary Loads in Web Content为YES
Drag the SSWKURL.h and SSWKURL.m files into your project.
Usage
Subclass SSWKURLProtocol like NSURLProtol.
Implement your own -startLoading: and -stopLoading.
Then call [yourWKURLConfiguration ssRegisterURLProtocol:[YourSSWKURLProtocol cl