美文网首页iOS踩过的坑系列iOS开发
iOS踩过的坑之WKWebView和JS交互

iOS踩过的坑之WKWebView和JS交互

作者: Shaw1211 | 来源:发表于2019-04-24 14:25 被阅读0次

    需求:一加载网页H5就要从客户端获取用户信息,但是又不能直接拼在URL中,防止信息泄露,所以采用JS调用iOS的方法,来获取用户信息。
    问题及解决方案:对于WebKit框架下,无法使用JSContext来向JS发消息,因此采用先被动接受JS发过来的消息,然后接收到消息后再主动调用JS的一个带参数的方法,将用户信息作为参数传过去这样的方式。

    解决方案:

    1. 首先引入WebKit框架
      #import <WebKit/WebKit.h>
    2. 配置webView和configuration
    @interface CYBCommunityVC () <WKNavigationDelegate, WKScriptMessageHandler, UIGestureRecognizerDelegate>
    
    @property (nonatomic, strong) WKWebView *webView;
    @property (nonatomic, strong) WKWebViewConfiguration *configuration;
    
    @end
    
    1. 懒加载
    - (WKWebViewConfiguration *)configuration {
        if (!_configuration) {
            _configuration = [[WKWebViewConfiguration alloc] init];
        }
        return _configuration;
    }
    
    
    - (WKWebView *)webView {
        if (!_webView) {
            _webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) configuration:self.configuration];
            _webView.navigationDelegate = self;
            _webView.allowsBackForwardNavigationGestures = YES;
            [_webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"testwithiOS" ofType:@"html"]]]];
            WKUserContentController *userContent = self.configuration.userContentController;
            [userContent addScriptMessageHandler:self name:@"cybios"];
        }
        return _webView;
    }
    
    1. 实现代理协议
    #pragma mark UIGestureRecognizerDelegate
    - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
        DebugLog(@"开始加载");  
    }
    
    - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
        DebugLog(@"内容开始返回");
    }
    
    - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
        DebugLog(@"页面加载完成");        
    }
    - (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
        ErrorLog(@"页面加载失败");
    }
    
    - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
        DebugLog(@"js向iOS发送消息\n消息名称:%@消息体:%@", message.name, message.body);
        if ([message.body isEqualToString:@"fetchUserInfo"]) {
            [self invokeJSMethodToSendUserInfo];
        }
    }
    
    /** oc调用JS方法返回用户信息*/
    - (void)invokeJSMethodToSendUserInfo {
        NSDictionary *dict = @{@"type":@"0", @"userID":@"7f1903e18d203cfd1a9e4d93e08a9e65"};
        NSString *param = [dict modelToJSONString];
        NSString *jsMethod = [NSString stringWithFormat:@"fetchUserInfo(%@)", param];
        [_webView evaluateJavaScript:jsMethod completionHandler:^(id _Nullable obj, NSError * _Nullable error) {
            DebugLog(@"%@", obj);
        }];
    }
    
    1. 对应JS方面的代码
    function log() {
            window.webkit.messageHandlers.cybios.postMessage("fetchUserInfo");
        }
        function fetchUserInfo(userInfo){
            var x = document.getElementById('result');
            x.innerHTML=userInfo;
            return userInfo;
        }
    

    相关文章

      网友评论

        本文标题:iOS踩过的坑之WKWebView和JS交互

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