iOS-OC初级

WKWebView 小记

2018-08-15  本文已影响27人  秀才不才

WKWebView 不支持点击处理电话,邮件等格式化的URL,暂时记录下简单的webView处理

URL 特殊字符编码:
iOS9.0 之前:
NSString *encodedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,(CFStringRef)urlStr,(CFStringRef)@"!$&'()*+,-./:;=?@_~%#[]",NULL,kCFStringEncodingUTF8));
iOS9.0 之后:
NSString *encodedUrl = [url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]
WebView初始化 Session同步
//初始化时注入sessionID  暂时用着没问题
NSString *cookieStr = [NSString stringWithFormat:@"document.cookie='%@=%@;path=/';",ShareManager.urlCookie.name,ShareManager.urlCookie.value];
WKUserScript *wkScript = [[WKUserScript alloc] initWithSource:cookieStr injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
WKUserContentController *contentC = [[WKUserContentController alloc] init];
[contentC addUserScript:wkScript];
WKWebViewConfiguration *wkConfig = [[WKWebViewConfiguration alloc] init];
wkConfig.userContentController = contentC; 
webView = [[WKWebView alloc]initWithFrame:self.view.frame configuration:wkConfig];

//URL监听 记着释放
[self.wkWebView addObserver:self forKeyPath:@"URL" options:NSKeyValueObservingOptionNew context:nil];
WebView frame不正确的时候写了下面方法
- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
        
    if (@available(iOS 11.0, *)) {
        CGRect safeFrame = self.view.safeAreaLayoutGuide.layoutFrame;
        [self.wkWebView setFrame:CGRectMake(0, self.backOriginView.frame.origin.y, self.view.frame.size.width, safeFrame.size.height)];
    }
    else
    {
        float height = [[UIApplication sharedApplication] statusBarFrame].size.height;
        if (!self.navigationController.navigationBarHidden) {
            height = 0;
        }
        [self.wkWebView setFrame:CGRectMake(0, height, ScreenWidth, self.view.frame.size.height - height)];
    }
    
}
WebBridge 注入JS交互
第三方 `WebViewJavascriptBridge`类
registerHandler
callHandler

//JS方法退出Web类需要手动移除,否则类不释放
[self.bridge removeHandler:js];
可以判断页面退出吗???主要是手势返回
- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    if (!self.navigationController && //navigation
        !self.tabBarController &&   //tabbar
        !self.presentingViewController) //present
    {
        [self deleteHanderMethod];
    }
}
不这样会导致内存泄露???
在viewWillAppear设置
if (self.bridge) {
  //不设置 WKWebView 代理不执行
  [self.bridge setWebViewDelegate:self];
}
在viewWillDisappear 设置
[self.bridge setWebViewDelegate:nil];
WebViewDelegate
//绕过证书认证
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler {
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        NSURLCredential *card = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust];
        completionHandler(NSURLSessionAuthChallengeUseCredential,card);
    }else {
        completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
    }
}

//页面开始加载
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
  //
}
//页面加载完成
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
  //
}
//页面加载失败
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
   //
}
//收到响应后是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
    decisionHandler(WKNavigationResponsePolicyAllow);
}
-(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
    
    NSURL *linkUrl = navigationAction.request.URL;
    if (navigationAction.navigationType == WKNavigationTypeLinkActivated && [self.urlStr containsString:@"jumpWebUrl=1"]) {
        //url包含jumpWebUrl=1字段 允许跳转外部链接
        if (![linkUrl.host containsString:webView.URL.host]) {
            //当前链接域名不一致 跳转新H5类
            [self goWebViewController:@"" urlStr:navigationAction.request.URL.absoluteString];
            decisionHandler(WKNavigationActionPolicyCancel);
            return;//不return崩溃
        }
    }
    
    NSString *urlScheme = linkUrl.scheme;
    if (urlScheme.length && ([linkUrl.host containsString:@"itunes.apple.com"] || ![urlScheme containsString:@"http"])) {
        
        NSString *scheme = @"";
        if ([urlScheme isEqualToString:@"tel"]) {
            scheme = @"telprompt";//拨打电话☎️会弹窗提示
        } else {
            scheme = urlScheme;
        }
        
        if (IOS10_OR_LATER) {
            [[UIApplication sharedApplication]openURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@:%@",scheme,[linkUrl resourceSpecifier]]] options:@{} completionHandler:nil];
        } else {
            [[UIApplication sharedApplication]openURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@:%@",scheme,[linkUrl resourceSpecifier]]]];
        }
        decisionHandler(WKNavigationActionPolicyCancel);
        return;//不return崩溃
    }
    if (navigationAction.targetFrame == nil) {
        [webView loadRequest:navigationAction.request];
    }
    decisionHandler(WKNavigationActionPolicyAllow);
}

//弹窗
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
  //
}
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler {
  //
}
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler { 
  //
}

其他方法
goBack; //处理显示`返回``关闭`按钮
//禁止缩放 方法不是很完美 
 - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return nil;
}

其他缩放方法(没测试):这里

WKWebView暂告一段落了
上一篇下一篇

猜你喜欢

热点阅读