一.创建NSURLProtocol延展类在里面实现注册监听WKWebview中的指定协议头的网络请求和解除监听WKWebview中的指定协议头的网络请求
/**
注册监听WKWebview中的指定协议头的网络请求
@param scheme 协议头字符串
*/
+ (void)registerToWKWebviewWithScheme: (NSString *)scheme;
/**
解除监听WKWebview中的指定协议头的网络请求
@param scheme 协议头字符串
*/
+ (void)unregisterToWKWebviewWithScheme: (NSString *)scheme;
#import "NSUrlProtocol+Lemage.h"
#import <WebKit/WebKit.h>
@implementation NSURLProtocol (Lemage)
FOUNDATION_STATIC_INLINE Class ContextControllerClass() {
static Class cls;
if (!cls) {
cls = [[[WKWebView new] valueForKey:@"browsingContextController"] class];
}
return cls;
}
FOUNDATION_STATIC_INLINE SEL RegisterSchemeSelector() {
return NSSelectorFromString(@"registerSchemeForCustomProtocol:");
}
FOUNDATION_STATIC_INLINE SEL UnregisterSchemeSelector() {
return NSSelectorFromString(@"unregisterSchemeForCustomProtocol:");
}
/**
注册监听WKWebview中的指定协议头的网络请求
@param protocol 协议头字符串
*/
+ (void)registerToWKWebviewWithScheme: (NSString *)scheme {
Class cls = ContextControllerClass();
SEL sel = RegisterSchemeSelector();
if ([(id)cls respondsToSelector:sel]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[(id)cls performSelector:sel withObject:scheme];
#pragma clang diagnostic pop
}
}
/**
解除监听WKWebview中的指定协议头的网络请求
@param protocol 协议头字符串
*/
+ (void)unregisterToWKWebviewWithScheme: (NSString *)scheme {
Class cls = ContextControllerClass();
SEL sel = UnregisterSchemeSelector();
if ([(id)cls respondsToSelector:sel]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[(id)cls performSelector:sel withObject:scheme];
#pragma clang diagnostic pop
}
}
接着在写我们自己的URLProtocol(继承NSURLProtocol)并且实现NSURLSessionDelegate协议
+ (BOOL)canInitWithRequest:(NSURLRequest *)request {
if ([NSURLProtocol propertyForKey: @"你得标记" inRequest:request]) {
// 处理后的request会打上标记,在这里判断一下,如果打过标记的request会放过,防止死循环
return NO;
}
if ([request.URL.scheme caseInsensitiveCompare: @"我们需要处理的请求头"] == NSOrderedSame) {
return YES;
}
return NO;
}
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
return request;
}
- (void)startLoading{
NSMutableURLRequest* request = self.request.mutableCopy;
//在这是打上了印记,用来防止死循环
[NSURLProtocol setProperty:@YES forKey: @"你得印记" inRequest:request];
__block typeof(self) weakSelf = self;
if ([request.URL.scheme caseInsensitiveCompare: @"需要处理的请求头"] == NSOrderedSame) {
NSLog(@"--------------------------");
//替换图片数据
NSData *data = UIImageJPEGRepresentation([UIImage named:@"temp"],1.0f);
NSURLResponse* response = [[NSURLResponse alloc] initWithURL:self.request.URL MIMEType:@"image/png" expectedContentLength:data.length textEncodingName:nil];
[self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowed];
[self.client URLProtocol:self didLoadData:data];
[self.client URLProtocolDidFinishLoading:self];
}
}
//不写的话会崩溃
- (void)stopLoading {
}
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
[[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowed];
completionHandler(NSURLSessionResponseAllow);
}
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
[[self client] URLProtocol:self didLoadData:data];
}
在之后就是要在AppDelegate.h中注册我们自己定义的URLProtocol
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[NSURLProtocol registerClass:[自定义的URLProtocol class]];
[NSURLProtocol registerToWKWebviewWithScheme:@"要处理的请求头"];
}
网友评论