WKWebView的簡單使用,與js交互(js調用OC或swift方法)

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章