WKWebview 调用js的方法以及遇到的坑

今天做webview和js交互的诸多事宜。
众所周知wkwebview调用js的方法,要调用如下代码

- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;

//例如OC调用JS的方法 setName

   [webView evaluateJavaScript:@"setname('张三')" completionHandler:nil];

//此处 setname为JS定义的方法名, 内部 ‘张三’为传给JS的参数。 如果setname方法需要传入一个json或者array等非字符参数, 需要用format方法将其转为string类型,在调用evaluate方法。例如

   NSString * para = [NSString stringWithFormat:@"setname('%@')",json];

首先我要强调的是,这样的调用是没有问题的 但是在实际应用中,由于我比较笨,H5和JS的相关代码不懂,所以,即便是这样的方法调用方法也是看不懂的,因为实际开发过程中不会有简单的setname(张三)这么简单,接下来我说明一下我遇到的坑。

我的应用场景: 点击某个按钮判断iOS端是否打开了推送。
首先点击按钮 是OC调用JS,哪么是否开启了推送有一个YES和NO要传给JS端,我就是在给JS传参数的时候遇到的一些坑。

请看下面的代码。 其中parma 是我们要传给JS的参数 ,cbDispatcher是OC与JS约定好的方法名,只有掉相同的方法名才能掉的通,

NSDictionary * parma = @{@"status":@"0"};
            if ([NSJSONSerialization isValidJSONObject:parma]) {
                NSError * error;
                NSData * jsonData = [NSJSONSerialization dataWithJSONObject:parma options:NSJSONWritingPrettyPrinted error:&error];
                NSString * jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
                NSString * backStr = [NSString stringWithFormat:@"%@(%@,%@)",dicPrama[@"cbDispatcher"],dicPrama[@"callbackId"],jsonStr];
                
                [web evaluateJavaScript:backStr completionHandler:^(id _Nullable object, NSError * _Nullable error) {
                    NSLog(@" - %@ -- %@ --- ",error,object);
                }];
            }

如果这样写的话,会有报错,请看下图

[web evaluateJavaScript:[NSString stringWithFormat:@"cbDispatcher('cbDispatcher(2,%@)')",jsonStr] completionHandler:nil];

请不要这样写,最好能把completionHandler这个参数的block写成nil,因为可能,无法一遍就成功,这里可以打印错误吗,便于改成错误。
如下建议这样写:

[web evaluateJavaScript:backStr completionHandler:^(id _Nullable object, NSError * _Nullable error) {
                    NSLog(@" - %@ -- %@ --- ",error,object);
                }];

错误 Error Domain=WKErrorDomain Code=4 "A JavaScript exception occurred"
在这里插入图片描述

注意:遇到这个问题一定是 json解析dictionary出问题了,或者说拼接字符串时最后传的字符串格式有问题,所以,这个错误的大致意思是 JS 不认识你传过来的string。仔细看发现 在字符串中不应该加 那 一对单引号导致这个stringH5就不认识了.
修改如下:
在这里插入图片描述
注意我圈出来的和之前的区别,经这样修改就可以了
正确的截图,如果completionHandler参数中返回两个null那么表示传参就成功了。截图如下在这里插入图片描述

拓展 查资料,发现有说这是nsdictionary 在执行json解析的时候设置json格式不争取导致的。NSData * jsonData = [NSJSONSerialization dataWithJSONObject:parma options:NSJSONWritingPrettyPrinted error:&error]; option后的参数使用不正确,应该是NSData * jsonData = [NSJSONSerialization dataWithJSONObject:parma options:kNilOptions error:&error];这样

从字面意思看,NSJSONWritingPrettyPrinted 是指json格式是:写成漂亮的印刷,大概意思是:这样的json也是有格式的,这个写入选项会使用空格和缩进来使输出更有可读性。
如果这个选项没有设置,则生成紧凑合理的JSON表达式。
如果使用 kNilOptions 表示,没有什么格式,就是一长溜的字符串。
但是经过我的测试,这两种json格式我们的JS时都认可的 。可能有朋友的JS不认第一种格式。请谨慎使用。

我是磊怀 QQ:2849765859 欢迎各位大佬联系我。