WKWebView 其實是 UIWebView 的底層(應該可以這麼說)

為什麼要用WKWebView呢~其實是因為要呼叫JavaScript

讓網頁可以跟手機互相呼叫

但盡量使用純html的Code 因為有遇到ASP.NET 因為很多控制項是他們自己封裝的

手機版的WebView 會解析不出來會造成錯誤,但OSX版本的Safari卻又可以,但這又是另外一件事情了(ASP.NET 的問題是可以解決的

 

-本文開始-

首先

Framework 要加入 WebKit.framework

再來要

#import <WebKit/WebKit.h>

加入以下Delegate

@interface xxxViewController ()<WKScriptMessageHandler, WKNavigationDelegate,WKUIDelegate>

增加property

@property (nonatomic,strong) WKWebView* webView;

@property (nonatomic, strong) WKWebViewConfiguration * webConfig;

 

設定Delegate

self.webView.navigationDelegate = self;

self.webView.UIDelegate = self;

 

實現webConfig

#pragma mark - accessors

-(WKWebViewConfiguration*) webConfig {

    if (!_webConfig) {

        _webConfig = [[WKWebViewConfigurationalloc]init];

        WKUserContentController* userController = [[WKUserContentControlleralloc]init];

        [userController addScriptMessageHandler:selfname:@"這裡要對應你的JavaScript Code"];

        //例如:JavaScript 是 : window.webkit.messageHandlers.Sign.postMessage('abc');

        //JavaScript 要Call iOS的function 必須要執行 window.webkit.messageHandlers.Sign.postMessage('abc');

        //上面的abc 可以換成物件(Object)或是陣列(Array) App接到後判斷就可以轉換了

        //另外記得要用try catch包起來不然一般瀏覽器會有問題

        //你的Code就是下面這樣

        [userController addScriptMessageHandler:selfname:@"Sign"];

        _webConfig.userContentController = userController;

    }

    return_webConfig;

}

 

因為WKWebView不允許彈出視窗(alert),但是我們可以抓到彈出視窗的指令,並用原生的方式取代

/**

 *  web界面中有弹出警告框时调用

 *

 *  @param webView           实现该代理的webview

 *  @param message           警告框中的内容

 *  @param frame             主窗口

 *  @param completionHandler 警告框消失调用

 */

- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)())completionHandler {

    NSLog(@"runJavaScriptAlert %@",message);

    UIAlertController *alertController = [UIAlertControlleralertControllerWithTitle:message

                                                                             message:nil

                                                                      preferredStyle:UIAlertControllerStyleAlert];

    [alertController addAction:[UIAlertActionactionWithTitle:@"OK"

                                                        style:UIAlertActionStyleCancel

                                                      handler:^(UIAlertAction *action) {

                                                          completionHandler();

                                                      }]];

    [self presentViewController:alertController animated:YEScompletion:^{}];

}

還有兩個類似的需要可以自己實現

confirm

- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame
completionHandler:(void (^)(BOOL result))completionHandler

 

Text

- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText
initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *result))completionHandler

 

再來抓到我們剛剛設定的JavaScript Handler

#pragma mark -WKScriptMessageHandler

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {

    if ([message.nameisEqualToString:@"Sign"]) {

        NSLog(@"Sign");

        //Do Something...

    }

}

 

若要Call JavaScript Function 也可以

-(NSString *)getResultCode

{

    NSString *exec = [NSStringstringWithFormat:@"getresultcode(\"%@\");", resultCode];

        [self.webViewevaluateJavaScript:exec completionHandler:^(id response, NSError * error) {

            if (error) {

                NSLog(@"%@",error);

            }

        }];

    return resultCode;

}

但好像沒辦法直接存成變數讓JavaScript使用

 

差不多就這樣~沒想到居然有這種用法

以前都覺得根本不會用到

但似乎很多人都希望可以Call到原生的function再傳回

因為這樣就只需要一個網頁然後就可以用同個流程

不需要再另外用原生做個畫面出來了。

arrow
arrow
    創作者介紹
    創作者 Mr.Lin 的頭像
    Mr.Lin

    Mr.Lin

    Mr.Lin 發表在 痞客邦 留言(14) 人氣()