1.拦截方式
当js调用swift 或者oc方法时,我们可以用拦截的方式,进行交互。
例如有这样一个js方法
function buttonclick() {
// body..
//这个地方可以用iframe进行拦截
//window.location.href = “#{‘do’:’buttonclick’,’good_id’:’100’}”;
}
当h5页面按钮点击事件触发时,我们wkwebview的navigationdelegate的代理方法会拦截到href 的改变
navigationAction.request.mainDocumentURL?.relativeString 此字符串即为#{‘do’:’buttonclick’,’good_id’:’100’} 这样的字符串,再经过处理,即可得到json字符串,处理json我们就得心应手了。参数得传递可以直接在json里面传递过来,即可完成js对客户端的方法的调用。
下面代码分为swift 和OC版本:
import UIKit
import WebKit
@objc class BasicWkWebViewController: BasicViewController,WKNavigationDelegate {
var webView: WKWebView?
init(url: String!) {
super.init(nibName: nil, bundle: nil)
let requsetUrl = URL.init(string: url)
let request = URLRequest.init(url: requsetUrl!)
let wkWeb = WKWebView.init(frame: self.view.bounds)
self.view.addSubview(wkWeb)
wkWeb.load(request)
wkWeb.navigationDelegate = self;
self.webView = wkWeb
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//js事件触发
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
let requeststr = navigationAction.request.mainDocumentURL?.relativeString;
if requeststr?.range(of: "#") != nil{
let data = self.requesParmeter(request: requeststr!)
print(data)
if let doStr = data["do"]{
let selector = NSSelectorFromString(doStr + ":")
if self.responds(to: selector) {
self.perform(selector, with: data)
decisionHandler(WKNavigationActionPolicy.cancel)
return
}
}
}
decisionHandler(WKNavigationActionPolicy.allow)
}
//进行参数得解析
func requesParmeter(request: String) ->NSDictionary{
let array = request.components(separatedBy: "#")
let requestStr = array.last
return self.getrequestjson(requeststr: requestStr!)
}
func getrequestjson(requeststr: String) ->NSDictionary {
let requestString = requeststr.removingPercentEncoding
let strData = requestString?.data(using: String.Encoding.utf8)
do {
let weatherDic = try JSONSerialization.jsonObject(with: strData!, options: .mutableLeaves)
return weatherDic as! NSDictionary;
} catch { }
return NSDictionary()
}
override func viewDidLoad() {
super.viewDidLoad()
//self.webView.addObserver(self, forKeyPath: "title", options: .new, context: nil)
}
// override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
// super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
// if keyPath == "title" {
// self.title = change?[NSKeyValueChangeKey.newKey] as? String
// }
// }
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// deinit {
// self.webView?.removeObserver(self, forKeyPath: "title")
// }
}
//js方法
extension BasicWkWebViewController{
}
OC版本
//拦截的方式
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
NSString *str = navigationAction.request.mainDocumentURL.relativeString;
if ([str containsString:@"#"]) {
NSDictionary *dic = [self requestParmeter:str];
NSString *doStr = dic[@"do"];
if (doStr.length) {
SEL selector = NSSelectorFromString([NSString stringWithFormat:@"%@:",doStr]);
if ([self respondsToSelector:selector]) {
SuppressPerformSelectorLeakWarning(
[self performSelector:selector withObject:dic];
);
decisionHandler(WKNavigationActionPolicyCancel);
}
}
}
decisionHandler(WKNavigationActionPolicyAllow);
}
//- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
//{
// NSString *requeststr=navigationAction.request.mainDocumentURL.relativeString;
// if([requeststr rangeOfString:@"#"].location!=NSNotFound)
// {
// NSArray *arr = [requeststr componentsSeparatedByString:@"#"];
// requeststr = [arr objectAtIndex:1];
NSDictionary *data = [Comm getrequestjson:requeststr];
if ([data.allKeys containsObject:@"do"]){
NSString *str = data[@"do"];
// if ([requeststr rangeOfString:str].location != NSNotFound) {
SEL selector = NSSelectorFromString([str stringByAppendingString:@":"]);
if ([self respondsToSelector:selector]) {
[self performSelector:selector withObject:data];
decisionHandler(WKNavigationActionPolicyCancel);
}
}
// }
// decisionHandler(WKNavigationActionPolicyAllow);
//}
-(NSDictionary *)requestParmeter:(NSString *)str{
NSArray *arr = [str componentsSeparatedByString:@"#"];
NSString *requesrStr = arr.lastObject;
return [self getrequestjson:requesrStr];
}
-(NSDictionary *)getrequestjson:(NSString *)requestStr{
NSString *str = requestStr.stringByRemovingPercentEncoding;
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
return [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
}
wkwebview弹窗的显示
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:([UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler();
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
// DLOG(@"msg = %@ frmae = %@",message,frame);
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:([UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
completionHandler(NO);
}])];
[alertController addAction:([UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(YES);
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:prompt message:@"" preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.text = defaultText;
}];
[alertController addAction:([UIAlertAction actionWithTitle:@"完成" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(alertController.textFields[0].text?:@"");
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
2.JavaScriptCore ios7.0之后推出的,只适用于UIWebView
通过注册自定义对象,js调用对象方法,具体的用法网上有很多例子
3.通过messageHandler (适用于WKWebView)
webView.configuration.userContentController.add(self,”aasdsjk”)
通过代理方法 调用原生方法
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "aasdsjk" {
JKLog(message)
JKLog(message.body)
}
}
原生调用JS方法:
let textJS = "callback('ios测试')"//javascript
//context?.evaluateScript(textJS)
webView.evaluateJavaScript(textJS) { (any, error) in
JKLog(error)
JKLog(any)
}
另外推荐一个自己写的弹出自定义视图的工具,支持pod 给个Star