iOS WKWebView & JS

作者: _YZG_ | 来源:发表于2018-03-03 15:44 被阅读159次

    UIWebView iOS 2.0 出现 ,WKWebView iOS 8.0出现
    在微信中可以输入:switchweb进行切换

    但是发现个问题,现在输入之后切换不了了,微信版本6.6.5 系统版本11.2.6,有了解的请评论告知,感激不尽。

    切换说明:微信公众平台技术文档

    :switchweb

    一、UIWebView&WKWebView选择&比较

    WKWebView是苹果在WWDC2014发布会中发布的iOS 8的时候公布的WebKit时候使用的新型的H5容器。它与UIWebView相比较,拥有更快的加载速度和性能,更低的内存占用。将UIWebViewDelegate和UIWebView重构成了14个类,3个协议,可以让开发者进行更加细致的配置。

    我的观点哈,能用WKWebView就用,除非一些特殊情况,如要适配iOS 7等,WKWebView的请求不能被NSURLProtocol截获等等。但是可以通过其他方式,如https://github.com/WildDylan/WKWebViewWithURLProtocol是通过私有API让WKWebView可以支持NSURLProtocol的

    二、关于JS交互

    使用https://github.com/marcuswestin/WebViewJavascriptBridge支持UIWebView与WKWebView,并且在Android有一套对应的https://github.com/lzyzsd/JsBridge,前端只需要写一套。

    WebViewJavascriptBridge使用链接

    其实不管网页怎么写,都有对应的方法,只是方便不方便的问题,喜欢就好啦,无所谓。

    正文 WKWebView & JS

    三、动态加载并运行JS代码

    // 图片缩放的js代码
    NSString *js = @"js code";
    // 根据JS字符串初始化WKUserScript对象
    WKUserScript *script = [[WKUserScript alloc] initWithSource:js injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
    // 根据生成的WKUserScript对象,初始化WKWebViewConfiguration
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    [config.userContentController addUserScript:script];
    _webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:config];
    [_webView loadHTMLString:@"html code"baseURL:nil];
    [self.view addSubview:_webView];
    

    四、OC 执行 JS 代码

    //javaScriptString是JS方法名,completionHandler是异步回调block
    [self.webView evaluateJavaScript:javaScriptString completionHandler:completionHandler];
    
    

    五、JS 执行 OC 代码

    JS在调用OC方法的时候用下面的方式

    window.webkit.messageHandlers.<name>.postMessage(<messageBody>)
    

    例:

    // 没有参数也要写null否则代理方法不会执行
    window.webkit.messageHandlers.closeMe.postMessage(null);
    

    在iOS端

    //OC注册供JS调用的方法
    [[self.webView configuration].userContentController addScriptMessageHandler:self name:@"closeMe"];
    
    
    WKScriptMessageHandler 代理
    //OC在JS调用方法做的处理
    - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
        NSLog(@"JS 调用了 %@ 方法,传回参数 %@",message.name,message.body);
    }
    
    

    六、内存泄露解决方案

    思路是另外创建一个代理对象,然后通过代理对象回调指定的self
    具体如下

    @interface HPWeakScriptMessageDelegate : NSObject 
    @property (nonatomic, weak) id<WKScriptMessageHandler> scriptDelegate;
    
    - (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate;
    
    @end
    
    @implementation HPWeakScriptMessageDelegate
    - (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate
    {
        self = [super init];
        if (self) {
            _scriptDelegate = scriptDelegate;
        }
        return self;
    }
    
    - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
    {
        [self.scriptDelegate userContentController:userContentController didReceiveScriptMessage:message];
    }
    
    
    @end
    

    使用HPWeakScriptMessageDelegate

    //设置addScriptMessageHandler与name.并且设置<WKScriptMessageHandler>协议与协议方法
    [[self.wkWebView configuration].userContentController addScriptMessageHandler:[[WeakScriptMessageDelegate alloc] initWithDelegate:self] name:@"对象名"];
    

    销毁

    - (void)dealloc {
        ...
        [[self.webView configuration].userContentController removeScriptMessageHandlerForName:@"对象名"];
        ...
    }
    

    七、WKWebView Alert无法弹出问题

    实现WKUIDelegate

    - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
        [alertController addAction:([UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            completionHandler();
        }])];
        [self presentViewController:alertController animated:YES completion:nil];
    }
    

    相关文章

      网友评论

        本文标题:iOS WKWebView & JS

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