iOS问题汇总之iOS应用 - 浏览器及WKWebView关键点
08 September 2020
iOS问题汇总之iOS应用 - 浏览器及WKWebView关键点
WKWebView
关键代码
self.wkWebView.allowsBackForwardNavigationGestures = YES;
[self.wkWebView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
[self.wkWebView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:nil];
关键类与方法
WKUserContentController
//添加消息处理
self.configuration.userContentController = [WKUserContentController new];
[self.configuration.userContentController addScriptMessageHandler:self name:@"webViewReload"];
//添加UserScript
\- (void)addUserScript:(WKUserScript *)userScript;
//处理js端消息
\- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;
//处理当接收到验证窗口时
\- (void) webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
//切换用户代理模式
//私有方法:- (void)_setCustomUserAgent:(id)arg1;
WKNavigationDelegate
decidePolicyForNavigationAction:
WKScriptMessageHandler
WKUIDelegate
//处理页面的promt弹窗
//此方法可以让我们得知点击了哪个buttin,回传button index值
UIActionSheetDelegate
\- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
WKWebViewConfiguration WKProcessPool 单例
configuration.processPool = [WKProcessPool new];
//判断跳转类型,在做容器内外跳转可借用
\- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
if(navigationAction.navigationType == WKNavigationTypeReload ||
navigationAction.navigationType == WKNavigationTypeBackForward ||
navigationAction.navigationType == WKNavigationTypeFormSubmitted ||
navigationAction.navigationType == WKNavigationTypeFormResubmitted ){
decisionHandler(WKNavigationActionPolicyAllow);
return;
}
AdblockRules
基本过滤规则
-
- 通配符;
- @@表示例外规则符;
-
管道符 表示过滤规则终止; -
双管道符 表示域名前匹配; - 标记分隔符^表示单个分隔符的占位符。有时,您可能需要在过滤器中接受任何分隔符。分隔符可以是任何东西,除了一个字母,一个数字或以下情况之一:_,-,.,%。地址的末尾也可被视作一个分隔符。
- 感叹号!表示注释。!开头的行会被默认为注释行,不被执行。
- $表示过滤器选项;
规则库:EasyList
ad request 拦截原理
关键方法:e.preventDefault();
var filter = AdBlocker.checkFilterMatch(e.url, tagType, documentHost);
if(filter instanceof BlockingFilter) {
e.preventDefault();
......
无图模式原理
js修改document加载行为
document.addEventListener("beforeload", ImageBlocker.blockImages, true);
/*blockImages beforeload*/
ImageBlocker.blockImages = function() {
var isImage = event.url.match(/.jpg/i) || event.url.match(/.png/i) || event.url.match(/.gif/i) || event.url.match(/.jpeg/i) || event.url.match(/.bmp/i);
if (isImage) {
event.preventDefault();
}
var isImgTag = event.target.tagName == 'IMG';
if (isImgTag) {
event.preventDefault();
}
}
//
/*替换background-image*/
ImageBlocker.removeBackgroundImages = function() {
//alert('=====removeBackgroundImages')
if (ImageBlocker.enable) {
var bgImgs = document.body.querySelectorAll('*[style^=\"background-image:\"]');
for (var j = 0; j < bgImgs.length; j++) {
var bgImg = bgImgs[j];
bgImg.style.backgroundImage = '';
}
};
}
Cookie注入两种方法
- swizzle loadRequest
[WKWebView lwwk_swizzleMethod:@selector(loadRequest:) withMethod:@selector(myLoadRequest:)];
分iOS11以下与iOS11以上不同
iOS11以下,直接:
NSDictionary<NSString *, NSString *> *requestHeaderFields = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
[mRequest setHTTPShouldHandleCookies:YES];
[mRequest setAllHTTPHeaderFields:requestHeaderFields];
iOS11以上,要注意 setCookie:completionHandler:^{}
可能不会回调的bug;
- 使用js方法:使用
wkWebView evaluateJavaScript:@"document.cookie"
方法;