美文网首页
iOS WKWebView与JS交互

iOS WKWebView与JS交互

作者: YangSHP | 来源:发表于2019-05-24 12:10 被阅读0次

    1.OC调用JS方法

        NSString *shareMethod = @"share('参数1')";
        [self.webView evaluateJavaScript:shareMethod completionHandler:^(id _Nullable objStr, NSError * _Nullable error) {
        }];
    

    2.JS调用OC的方法

    1.初始化WKWebView时,调用addScriptMessageHandler:name:方法,name为js中的方法名

      - (void)setupWKWebView {
        //cookie
        WKCookieSyncManager *manager = [WKCookieSyncManager sharedWKCookieSyncManager];
        cookieStr = [manager setCookieWithIsCustomMsg:_chatCustomMsgBool];
        WKUserScript *cookieScript = [[WKUserScript alloc] initWithSource:cookieStr injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
        //初始化WKWebViewConfiguration
        WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
        //方法集合
        ocAndJSMethodArr = [Helper jsCallOCMethodArr];
        //初始化WKUserContentController
        userContentController = [[WKUserContentController alloc] init];
        for (NSString *methodStr in ocAndJSMethodArr) {//注册供js调用的方法
            [userContentController addScriptMessageHandler:self name:methodStr];
        }
        configuration.preferences.javaScriptCanOpenWindowsAutomatically = YES;
        [userContentController addUserScript:cookieScript];
        configuration.userContentController = userContentController;
        configuration.preferences.javaScriptEnabled = YES;
     //初始化WKWebView
        _webView = [[WKWebView alloc] initWithFrame:self.view.bounds) configuration:configuration]; 
        _webView.navigationDelegate = self;
        _webView.UIDelegate = self;
        [self.view addSubview:_webView];
        
        _mutRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:_urlStr] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:15];
        //设置cookie
        NSDictionary *cookiesDcit = [CustomeSetWebViewCookie setWebViewCookieWithURL:_urlStr isCustomMsg:NO];
        [_mutRequest setValue: [cookiesDcit objectForKey:@"Cookie"] forHTTPHeaderField: @"Cookie"];
    

    h5:类似如下代码

    window.webkit.messageHandlers.share.postMessage() 
    

    2.实现WKScriptMessageHandler代理方法,当js调用scan方法时,会回调此代理方法:

    //加载页面数据完成
    - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
        DLog(@"加载页面完成"); 
        NSMutableString *mutMethodStr = [[NSMutableString alloc] init];
        //由于h5那边没有按照类似于“window.webkit.messageHandlers.share.postMessage() ”的语法处理,以及为了JS通过类似于“Test_APP”的对象调用OC方法,所以通过注入一段以下这样的JS代码给网页以便本地调用
        for (int i=0; i<ocAndJSMethodArr.count; i++) {
            if (i<ocAndJSMethodArr.count-1) {
                [mutMethodStr appendFormat:@"\"%@\",",ocAndJSMethodArr[i]];
            } else {
                [mutMethodStr appendFormat:@"\"%@\"",ocAndJSMethodArr[i]];
            }
        }
        NSString *promptCode = [NSString stringWithFormat:@"(function(appName, methods){window[appName] = {};methods.forEach(function(v){window[appName][v] = function(a){window.webkit.messageHandlers[v].postMessage(a);}});})(\"%@\",[%@]);console.info(Test_APP);",JSAndOCObject,mutMethodStr];
        [_webView evaluateJavaScript:promptCode completionHandler:nil];
    //这段是为了处理弹框
    /*
    NSDictionary *dict = @{@"AlertVal":@"0",@"functionName":functionName};
                    NSString *jsStr = [NSString stringWithFormat:@"iosCallBack('getAlertVal','%@')",[Helper dictionaryToJson:dict]];
                    jsStr = [jsStr stringByReplacingOccurrencesOfString: @"\r" withString:@""];
                    jsStr = [jsStr stringByReplacingOccurrencesOfString: @"\n" withString:@""];
                    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                        [jsContext evaluateScript:jsStr];
                    });
    */
        NSString *functionCallStr = [NSString stringWithFormat:@"function iosCallBack (functionName, arg){window[functionName](arg);}"];
        [_webView evaluateJavaScript:functionCallStr completionHandler:nil];
    }
    
    #pragma mark - WKScriptMessageHandler
    - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    //    if ([message.name isEqualToString:@"share"]) {
    //        //调用原生分享
    //    }
        if(message.name ==nil || [message.name isEqualToString:@""])
            return;
        //message.body 传过来值
        //message.name  js发送的方法名称
        [self.jsNativeMethod nativeDidReceiveScriptMessageName:message.name messageBody:message.body];
    }
    - (JSNativeMethod *)jsNativeMethod {
        if (!_jsNativeMethod) {
            _jsNativeMethod = [[JSNativeMethod alloc] init];
        }
        return _jsNativeMethod;
    }
    

    注:页面销毁时,需要移除掉所调用的方法

    - (void)removeScriptMessage {
        //注册的方法要在view dealloc前 remove 否则 不走 dealloc,会循环引用
        for (NSString *nameStr in ocAndJSMethodArr) {
            [userContentController removeScriptMessageHandlerForName:nameStr];
        }
    }
    

    相关文章

      网友评论

          本文标题:iOS WKWebView与JS交互

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