美文网首页WKwebView
UIWebView 改为 WKWebView

UIWebView 改为 WKWebView

作者: _compass | 来源:发表于2020-10-22 18:16 被阅读0次

    以前项目中使用UIWebView的,现在要强制改为WKWebView了。
    注意以下几点:

    1、WKWebView的配置与创建:

    #import <WebKit/WebKit.h>
    // 配置:
    // 创建网页配置对象
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    // 跨域
    [config setValue:@YES forKey:@"_allowUniversalAccessFromFileURLs"];
    
    // 创建设置对象
    WKPreferences *preference = [[WKPreferences alloc]init];
    //最小字体大小 当将javaScriptEnabled属性设置为NO时,可以看到明显的效果
    preference.minimumFontSize = 0;
    //设置是否支持javaScript 默认是支持的
    preference.javaScriptEnabled = YES;
    // 在iOS上默认为NO,表示是否允许不经过用户交互由javaScript自动打开窗口
    preference.javaScriptCanOpenWindowsAutomatically = YES;
    config.preferences = preference;
    
    // 是使用h5的视频播放器在线播放, 还是使用原生播放器全屏播放
    config.allowsInlineMediaPlayback = YES;
    //设置视频是否需要用户手动播放  设置为NO则会允许自动播放
    config.requiresUserActionForMediaPlayback = YES;
    //设置是否允许画中画技术 在特定设备上有效
    config.allowsPictureInPictureMediaPlayback = YES;
    // 初始化
    _webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) configuration:config];
    // UI代理
    _webView.UIDelegate = self;
    // 导航代理
    _webView.navigationDelegate = self;
    // 是否允许手势左滑返回上一级, 类似导航控制的左滑返回
    _webView.allowsBackForwardNavigationGestures = YES;
    

    2、WKWebView加载网页:

    此处分为加载线上与本地网页:

    2.1.加载线上网页:

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.jianshu.com"]];
    [_webView loadRequest:request];
    

    2.2.加载本地html:

    html放在沙盒,或者工程的文件夹内,均可加载:

    NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"file://%@", htmlPath]];
    // 假如你的html路径为xxx/h5/index.html,那么htmlPathFolder就是xxx/h5这个文件夹,
    NSURL* baseURL = [NSURL URLWithString:[NSString stringWithFormat:@"file://%@", htmlPathFolder]];
    // 加载本地文件的方式加载
    [_webView loadFileURL:url allowingReadAccessToURL:baseURL];
    

    假如加载本地文件出现白页,请检查:
    1.是否在WKWebViewConfiguration设置了跨域;
    2.allowingReadAccessToURL后面的这个路径是否设置正确;
    3.loadFileURL后面这个路径是否正确;

    3、WKWebView中的js与app交互:

    之前项目中用的UIWebView,其中UIWebView中js调用app方式已经不能用了,所以需要修改前端方法。当然网上有种可以注入js方法,在不修改前端情况下,只修改app端,但是当js与app交互非常复杂的情况下,可能容易出错。
    通过注入js方式,只修改app端的方法参照以下链接:
    https://www.jianshu.com/p/7546f75cd1af

    以下WKWebView中js与app交互写法:

    3.1 js调用app:

    前端异步发送写法:

       function onClickCamara() {
            var path = "file:///13_1.jpg";
            if (isAndroid()) {
                window.ourapp.openCamara(path);
            } else {
                // UIWebView的写法:
                // ourapp.openCamara(path);
                // 现在修改成WKWebView的写法:  
               window.webkit.messageHandlers.openCamara.postMessage(path);
            }
        }
    

    app端异步注册消息写法:

    // 注册异步发送消息:
    [config.userContentController addScriptMessageHandler:self name:@"openCamara"];
    

    app端异步响应:

    - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
         if ([message.name isEqual:@"openCamara"]) {
           // do you work
          // message.body就是上面前端传递的参数
        } else if ([message.name isEqual:@"otherMessage"]) {
            
        }
    }
    

    前端需要获取信息:

    var userInfo = window.prompt('getUserinfo');
    

    app端直接在以下方法里获取:

    - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler{
        if (prompt) {
            if ([prompt isEqualToString: @"getUserInfo"]) {
              NSString* userInfo = [self getUserInfo];
              completionHandler(userInfo);
            } 
        }
    }
    

    前端会获取到userInfo的值。

    3.2 app调用js:

    以前使用UIWebView的时候,需要用"setTimeout"立即执行JavaScript,现在替换为WKWebView就不需要了。
    app端调用js的写法:

     // 这里开始一直调用不成功,后来替换了多余的/n和\才成功的.
    NSString*  jsonStringFirst = [json stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    jsonStringFirst = [jsonStringFirst stringByReplacingOccurrencesOfString:@"\\" withString:@""];
    NSString* jsonStringSecond = @"second";
    dispatch_async(dispatch_get_main_queue(), ^{
       NSString* function = [NSString stringWithFormat:@"jsFunction(\'%@\', \'%@\')", jsonStringFirst, jsonStringSecond];
       [_webView evaluateJavaScript:function completionHandler:^(id _Nullable object, NSError * _Nullable error) {
        // do you work.
       }];
    });
    

    在js(前端)中,有一个函数与以上代码对应:

     function jsFunction(argFirst, argSecond) {
          // 此处的jsFunction与app里调用一致,argFirst和即为上面的json,argSecond为app传递的第二个参数。
     }
    

    最后别忘了在dealloc中remove到注册的ScriptMessage。

    其他的使用方法就按照其他教程即可。

    相关文章

      网友评论

        本文标题:UIWebView 改为 WKWebView

        本文链接:https://www.haomeiwen.com/subject/eajkmktx.html