×

IOS WKWebview 和JS交互

96
John_LS
2016.07.25 12:01* 字数 366

IOS WKWebview 使用集锦

1、alert textInput等UI交互解决方法

如果需要与在JS调用alertconfirmprompt函数时,通过JS原生来处理,而不是调用JS的alertconfirmprompt函数,那么需要设置UIDelegate,在得到响应后可以将结果反馈到JS端:
1、首先设置WKUIDelegate代理

// 与webview UI交互代理
_web_webView.UIDelegate =self;

2、然后:
与JS原生的alertconfirmprompt交互,将弹出来的实际上是我们原生的窗口,而不是JS的。在得到数据后,由原生传回到JS:

#pragma mark - WKUIDelegate
- (void)webViewDidClose:(WKWebView *)webView {
     NSLog(@"%s", __FUNCTION__);
}
 
// 在JS端调用alert函数时,会触发此代理方法。
// JS端调用alert时所传的数据可以通过message拿到
// 在原生得到结果后,需要回调JS,是通过completionHandler回调
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
  NSLog(@"%s", __FUNCTION__);
  UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"alert" message:@"JS调用alert" preferredStyle:UIAlertControllerStyleAlert];
  [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
    completionHandler();
  }]];
  
  [self presentViewController:alert animated:YES completion:NULL];
  NSLog(@"%@", message);
}
 
// JS端调用confirm函数时,会触发此方法
// 通过message可以拿到JS端所传的数据
// 在iOS端显示原生alert得到YES/NO后
// 通过completionHandler回调给JS端
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler {
  NSLog(@"%s", __FUNCTION__);
  
  UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"confirm" message:@"JS调用confirm" preferredStyle:UIAlertControllerStyleAlert];
  [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
    completionHandler(YES);
  }]];
  [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
    completionHandler(NO);
  }]];
  [self presentViewController:alert animated:YES completion:NULL];
  
  NSLog(@"%@", message);
}
 
// JS端调用prompt函数时,会触发此方法
// 要求输入一段文本
// 在原生输入得到文本内容后,通过completionHandler回调给JS
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler {
  NSLog(@"%s", __FUNCTION__);
  
  NSLog(@"%@", prompt);
  UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"textinput" message:@"JS调用输入框" preferredStyle:UIAlertControllerStyleAlert];
  [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
    textField.textColor = [UIColor redColor];
  }];
  
  [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
    completionHandler([[alert.textFields lastObject] text]);
  }]];
  
  [self presentViewController:alert animated:YES completion:NULL];
}
 

2、 WKWebview与JS交互

1、WK调用JS

[_web_webView evaluateJavaScript:@"getImages()" completionHandler:^(id _Nullable script, NSError * _Nullable error) {
        
    }];

参数1:@param 是调用的js方法,并传值
参数2:如果JavaScript 代码出错, 可以在completionHandler 进行处理.

2、2.js向oc中传值使用的时WKWebView注册WKScriptMessageHandler代理

 //设置网页的配置文件
 WKWebViewConfiguration * Configuration = [[WKWebViewConfiguration
                                               alloc]init];
///添加js和wkwebview的调用
_userContentController =[[WKUserContentController alloc]init];
[_userContentController addScriptMessageHandler:self  name:@"aaa"];//注册一个name为alert的js方法
Configuration.userContentController = _userContentController;
_web_webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 300,500) configuration:Configuration];
#pragma mark 设置wkwebview的WKScriptMessageHandler代理方法
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(nonnull WKScriptMessage *)message{
    if ([message.name isEqualToString:@"aaa"]) {
        // 打印所传过来的参数,只支持NSNumber, NSString, NSDate, NSArray,
        // NSDictionary, and NSNull类型
        NSLog(@"%@", message.body);
    }
}

因为[_userContentController addScriptMessageHandler:self name:@"aaa"];//注册一个name为aaa的js方法所以要在页面销毁的时候,释放掉

///关闭web页时会释放内存
[_userContentController removeScriptMessageHandlerForName:@"aaa"];

js代码

window.webkit.messageHandlers.myName.postMessage(message);

3、使用- (nullable WKNavigation *)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL加载HTML标签并且调取本地的JS文件

1、添加js文件到目录下,需要注意的是,js文件和图片一样属于资源文件,确保添加到Copy Bundle Resources

42C13F62-A6AB-4C69-AB55-BA5652F39579.png

2、将js文件转为NSData添加到标签中

NSString* pathJs=[[NSBundle mainBundle]pathForResource:@"newsInfo" ofType:@"js"];
        NSData *jsData=[NSData dataWithContentsOfFile:pathJs];
        NSString *jsSource = [NSString stringWithFormat:@"data:js;base64,%@",[jsData base64Encoding]];
        NSString *str_Header=[NSString stringWithFormat:@"<script src=\"%@\"></script>",jsSource ];

3、调用标签即可

[_web_webView loadHTMLString:[NSString stringWithFormat:@"%@%@",str_Header,str_Html]  baseURL:nil];

4、添加本地图片,同本地js文件

//编码图片
- (NSString *)htmlForJPGImage:(UIImage *)image
{
    NSData *imageData = UIImageJPEGRepresentation(image,1.0);
    NSString *imageSource = [NSString stringWithFormat:@"data:image/jpg;base64,%@",[imageData base64Encoding]];
    return [NSString stringWithFormat:@"<img src = \"%@\" />", imageSource];
}

IOS UIKit和动画
Web note ad 1