ios wkweb设置图片_iOS WKWebView (NSURLProtocol)拦截js、css,图片资源
項(xiàng)目地址github:HybirdWKWebVIew
HybridNSURLProtocol
一個(gè)基于WKWebView的hybirde的容器。能攔截所有WKWKWebView的的css,js,png等網(wǎng)絡(luò)請(qǐng)求的demo
NSURLProtocol 子類,就可以對(duì) app 內(nèi)所有的網(wǎng)絡(luò)請(qǐng)求進(jìn)行:
[NSURLProtocol registerClass:[HybridNSURLProtocol class]]
可是在 WKWebView 中的請(qǐng)求卻完全不遵從這一規(guī)則,只是象征性+ (BOOL) canInitWithRequest:(NSURLRequest *)request 方法,之后的整個(gè)請(qǐng)求流程似乎就與 NSURLProtocol 完全無關(guān)了。
使我WKWebView 的一度認(rèn)為請(qǐng)求不遵守NSURLProtocol協(xié)議,所以不走 NSURLProtocol。這個(gè)也是很苦擾我的問題。導(dǎo)致我們hybird的容器1.0也是是用UIWebVIew實(shí)現(xiàn)的。
但在蘋果放在gittub的CustomHTTPProtocol,明顯感覺到WKWebview的也是遵守NSURLProtocol,要不也不會(huì)走+ (BOOL)canInitWithRequest:(NSURLRequest *)request;后來一個(gè)每天看博客和gittub的習(xí)慣幫助了我,找到一個(gè)大神的不久前開源庫。
使用了WKBrowsingContextController和registerSchemeForCustomProtocol。 通過反射的方式拿到了私有的 class/selector。通過kvc取到browsingContextController。通過把注冊(cè)把 http 和 https 請(qǐng)求交給 NSURLProtocol 處理。
[NSURLProtocol wk_registerScheme:@"http"];
[NSURLProtocol wk_registerScheme:@"https"];
下面直接上源代碼吧
//FOUNDATION_STATIC_INLINE 屬于屬于runtime范疇,你的.m文件需要頻繁調(diào)用一個(gè)函數(shù),可以用static inline來聲明。在SDWebImage讀取內(nèi)存的緩存也用到這個(gè)聲明。
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:");
}
@implementation NSURLProtocol (WebKitSupport)
+ (void)wk_registerScheme:(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
}
}
+ (void)wk_unregisterScheme:(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
}
}
注冊(cè)后,客戶端所有請(qǐng)求走+ (BOOL)canInitWithRequest:(NSURLRequest *)request。下面是打印的請(qǐng)求的log
+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
NSLog(@"request.URL.absoluteString = %@",request.URL.absoluteString);
NSString *scheme = [[request URL] scheme];
if ( ([scheme caseInsensitiveCompare:@"http"] == NSOrderedSame ||
[scheme caseInsensitiveCompare:@"https"] == NSOrderedSame ))
{
//看看是否已經(jīng)處理過了,防止無限循環(huán)
if ([NSURLProtocol propertyForKey:KHybridNSURLProtocolHKey inRequest:request])
return NO;
return YES;
}
return NO;
}
Aaron Swartz
request的重寫定向,request的重寫定向,替換百度知道的log
+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
NSLog(@"request.URL.absoluteString = %@",request.URL.absoluteString);
NSString *scheme = [[request URL] scheme];
if ( ([scheme caseInsensitiveCompare:@"http"] == NSOrderedSame ||
[scheme caseInsensitiveCompare:@"https"] == NSOrderedSame ))
{
//看看是否已經(jīng)處理過了,防止無限循環(huán)
if ([NSURLProtocol propertyForKey:KHybridNSURLProtocolHKey inRequest:request])
return NO;
return YES;
}
return NO;
}
這里最好加上緩存判斷,加載本地離線文件, 這個(gè)直接簡單的例子。
- (void)startLoading
{
NSMutableURLRequest *mutableReqeust = [[self request] mutableCopy];
//給我們處理過的請(qǐng)求設(shè)置一個(gè)標(biāo)識(shí)符, 防止無限循環(huán),
[NSURLProtocol setProperty:@YES forKey:KHybridNSURLProtocolHKey inRequest:mutableReqeust];
//這里最好加上緩存判斷,加載本地離線文件, 這個(gè)直接簡單的例子。
if ([mutableReqeust.URL.absoluteString isEqualToString:sourIconUrl])
{
NSData* data = UIImagePNGRepresentation([UIImage imageNamed:@"medlinker"]);
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];
}
else
{
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
self.task = [session dataTaskWithRequest:self.request];
[self.task resume];
}
}
下面是代碼效果圖
WechatIMG1.png
WechatIMG2.jpeg
項(xiàng)目地址:
github:HybirdWKWebVIew,對(duì)您有幫助,歡迎star。
有問題反饋
在使用中有任何問題,歡迎反饋給我,可以用以下聯(lián)系方式跟我交流
github:LiuShuoyu
接受啟發(fā)的作者的github
github:Yeatse CC
蘋果開發(fā)者文檔:apple
總結(jié)
以上是生活随笔為你收集整理的ios wkweb设置图片_iOS WKWebView (NSURLProtocol)拦截js、css,图片资源的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: querybuilder 排序_elas
- 下一篇: git菜单形式的_Idea:Git的常用