吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1580|回复: 9
收起左侧

[求助] WebViewJavascriptBridge APP与H5交互

[复制链接]
WolfAvenue 发表于 2021-6-9 11:56
现在H5能调用APP的方法这个样子
scan 是app 那边定义好了的方法
[JavaScript] 纯文本查看 复制代码
window.WebViewJavascriptBridge.callHandler("scan", {}, function (imgDataBase64) {
          
        });


请问,H5页面如何定义函数给APP调用,我看网上使用的是window.WebViewJavascriptBridge.registerHanlder 函数注册
但是registerHanlder 是未定义,registerHanlder 函数需要APP提供吗?

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

liesauer 发表于 2021-6-9 14:39
目前ios已经不让用uiwebview了,所以WebViewJavascriptBridge也不推荐使用了,原生调H5其实很简单,本质就是调用JS而已,给你参考下我的做法吧
[Objective-C] 纯文本查看 复制代码
#pragma mark - JS 交互
- (void)JSInvoke:(NSString *)function params:(NSDictionary *)params callback:(void (^)(NSDictionary *result, NSDictionary *params))callback {
    NSString *paramsStr = params ? [params yy_modelToJSONString] : @"null";
    if (!callback) {
        return [self runJS:[NSString stringWithFormat:@"%@(%@)", function, paramsStr] callback:nil];
    }
    WKWebView *webview = self.webViews[[self currentWindow]];
    if (webview) {
        NSString *token = [[NSUUID UUID] UUIDString];
        NSString *code = [NSString stringWithFormat:@"JSInvokeFinished('%@',%@(%@),%@);", token, function, paramsStr, paramsStr];
        self.callbacks[token] = [callback copy];
        dispatch_async(dispatch_get_main_queue(), ^{
            [webview evaluateJavaScript:code completionHandler:^(id _Nullable result, NSError * _Nullable error) {
                if (error) {
                    NSLog(@"异常发生%@", error);
                }
            }];
        });
    }
}

- (void)runJS:(NSString *)code on:(NSString *)token callback:(void(^)(NSDictionary *result, NSDictionary *params))callback {
    if (!token) {
        token = [self currentWindow];
    }
    WKWebView *webview = self.webViews[token];
    if (webview) {
        NSString *token = [[NSUUID UUID] UUIDString];
        if (callback) {
            self.callbacks[token] = [callback copy];
            code = [NSString stringWithFormat:@"%@;JSInvokeFinished('%@');", code, token];
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            [webview evaluateJavaScript:code completionHandler:^(id _Nullable result, NSError * _Nullable error) {
                if (error) {
                    NSLog(@"异常发生%@", error);
                }
            }];
        });
    }
}

- (void)runJS:(NSString *)code callback:(void(^)(NSDictionary *result, NSDictionary *params))callback {
    return [self runJS:code on:[self currentWindow] callback:callback];
}

liesauer 发表于 2021-6-9 14:54
顺便解释一下代码中的部分含义,我们的App是使用了多个WKWebView模拟电脑的Tab页概念的,所以在代码中你会看到多处[self currentWindow]或者self.webViews[token],这是为了获取最顶层或特定层的WebView(网页),并在其中执行想执行的JS代码,并且每次的Hybrid交互都会有一个唯一token指示,整个交互流程就是:
1. JS调原生,封装一个调用原生xxx的JS函数->调用一个封装好的nativeInvoke方法->调用postMessage->原生收到message->调用原生方法->原生执行JS代码(nativeInvokeFinished)
2. 原生调JS,封装一个调用JSxxx的原生方法->调用一个封装好的JSInvoke方法->调用封装好的runJS方法->调用wkwebview的evaluateJavaScript方法->执行对应的JS函数并调用JSInvokeFinished方法

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
WolfAvenue + 1 + 1 我很赞同!

查看全部评分

 楼主| WolfAvenue 发表于 2021-6-9 14:55
liesauer 发表于 2021-6-9 14:39
目前ios已经不让用uiwebview了,所以WebViewJavascriptBridge也不推荐使用了,原生调H5其实很简单,本质就 ...

objective-c语法好怪异哦,APP开发不太懂,能直接调用js 中的全局对象吗? 如果我在js window对象上定义好几个函数(window.js定义的函数名()),objective-c能直接调用吗?
liesauer 发表于 2021-6-9 15:00
WolfAvenue 发表于 2021-6-9 14:55
objective-c语法好怪异哦,APP开发不太懂,能直接调用js 中的全局对象吗? 如果我在js window对象上定义 ...

可以的,本质上所有原生调JS的操作,都是通过evaluateJavaScript方法完成的,你传过去的代码只要是任意合法的JS代码就行
 楼主| WolfAvenue 发表于 2021-6-9 15:10
liesauer 发表于 2021-6-9 15:00
可以的,本质上所有原生调JS的操作,都是通过evaluateJavaScript方法完成的,你传过去的代码只要是任意合 ...

那这个window.WebViewJavascriptBridge 对象是uiwebview 提供的么,这样看来看能自定义其他对象代替window.WebViewJavascriptBridge 功能把。目前 window.WebViewJavascriptBridge.callHandler函数有定义,registerHanlder 函数没定义,没看懂,原生也能定义js对象吧?
liesauer 发表于 2021-6-9 15:18
肯定可以啊,它只是封装了足够多的细节而已,让你看起来好像原生、JS能直接互相调用,但最终的本质都是离不开执行JS代码的,所以你完完全全可以在原生这边通过evaluateJavaScript方法来做到定义变量、定义方法函数、执行方法函数、赋值、取值,evaluateJavaScript方法就是让你写JS代码的!所以你写window.aaa = 100,又或者是window.test = () => console.log('test'),或者是window.test2(window.aaa),任意的JS代码都是可以的
debug_cat 发表于 2021-6-9 23:30
我今天才和web调试了,不知道你问的是ios还是安卓端,我知道安卓如何相互通信,ios没研究
 楼主| WolfAvenue 发表于 2021-6-10 09:13
莫问刀 发表于 2021-6-9 23:30
我今天才和web调试了,不知道你问的是ios还是安卓端,我知道安卓如何相互通信,ios没研究

安卓端的是如何通信的,用WebViewJavascriptBridge  这个吗?web端如何定义函数,安卓端调用js函数
debug_cat 发表于 2021-6-10 15:49
WolfAvenue 发表于 2021-6-10 09:13
安卓端的是如何通信的,用WebViewJavascriptBridge  这个吗?web端如何定义函数,安卓端调用js函数

我调试成功的是根据这个帖子成功的。https://www.jianshu.com/p/345f4d8a5cfa

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
WolfAvenue + 1 + 1 热心回复!

查看全部评分

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-26 02:56

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表