WKWebView 和 UIWebView的使用(js與iOS交互)

一材泄、UIWebView

1. 創(chuàng)建

// 1.創(chuàng)建webview悠鞍,并設(shè)置大小,
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height )];
// 2.創(chuàng)建請(qǐng)求
NSMutableURLRequest *request =[NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]];
// 3.加載網(wǎng)頁(yè)
[webView loadRequest:request];
// 4.添加到界面
[self.view addSubview:webView];

2. 一些實(shí)用函數(shù)

加載函數(shù)

- (void)loadRequest:(NSURLRequest *)request;
- (void)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;
- (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)textEncodingName baseURL:(NSURL *)baseURL;

UIWebView不僅可以加載HTML頁(yè)面参滴,還支持pdf强岸、word、txt砾赔、各種圖片等等的顯示蝌箍。下面以加載mac桌面上的png圖片:/Users/coohua/Desktop/bigIcon.png為例

// 1.獲取url
NSURL *url = [NSURL fileURLWithPath:@"/Users/coohua/Desktop/bigIcon.png"];
// 2.創(chuàng)建請(qǐng)求
NSURLRequest *request=[NSURLRequest requestWithURL:url];
// 3.加載請(qǐng)求
[self.webView loadRequest:request];

網(wǎng)頁(yè)導(dǎo)航刷新有關(guān)函數(shù)
// 刷新

- (void)reload;
// 停止加載
- (void)stopLoading;
// 后退函數(shù)
- (void)goBack;
// 前進(jìn)函數(shù)
- (void)goForward;
// 是否可以后退
@property (nonatomic, readonly, getter=canGoBack) BOOL canGoBack;
// 是否可以向前
@property (nonatomic, readonly, getter=canGoForward) BOOL canGoForward;
// 是否正在加載
@property (nonatomic, readonly, getter=isLoading) BOOL loading;

3 .代理協(xié)議使用:UIWebViewDelegate

//是否允許加載網(wǎng)頁(yè)
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    
    NSString *urlString = request.URL.absoluteString;
    NSLog(@"url=%@",urlString);
    return YES;
}
//開(kāi)始加載網(wǎng)頁(yè)
- (void)webViewDidStartLoad:(UIWebView *)webView {
    NSLog(@"開(kāi)始加載-url=%@--請(qǐng)求體--%@",webView.request.URL,webView.request.HTTPBody);
}
//網(wǎng)頁(yè)加載完成
- (void)webViewDidFinishLoad:(UIWebView *)webView {
     NSLog(@"加載完成-url=%@--請(qǐng)求體--%@",webView.request.URL,webView.request.HTTPBody);
     NSLog(@"網(wǎng)頁(yè)標(biāo)題:%@",[webView stringByEvaluatingJavaScriptFromString:@"document.title"]);
}
// 網(wǎng)頁(yè)加載錯(cuò)誤
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
    NSURLRequest *request = webView.request;
    NSLog(@"加載失敗-url=%@--錯(cuò)誤信息--%@",[request URL],error);
}

4.oc與js交互

主要有兩方面:js執(zhí)行OC代碼、oc調(diào)取寫(xiě)好的js代碼

  • oc執(zhí)行js代碼
NSString *scriptStr = @"showAlert('這里是oc調(diào)用js')";
[_webView stringByEvaluatingJavaScriptFromString:scriptStr];
  • js執(zhí)行OC代碼:

例如JS要調(diào)用getData方法:
則可以在UIWebView加載url完成后暴心,在其代理方法中添加要調(diào)用的getData方法:

-(void)webViewDidFinishLoad:(UIWebView *)webView
{
   JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    //定義好JS要調(diào)用的方法, getData就是調(diào)用的getData方法名
    context[@"getData"] = ^() {
       NSArray *array = [JSContext currentArguments];
      [array enumerateObjectsUsingBlock:^(JSValue *value,NSUInteger idx, BOOL *stop) {
             NSLog(@"%@", value.toString);    
        }];
    };
}

二妓盲、WKWebView 功能更強(qiáng)大

1.創(chuàng)建

先導(dǎo)入(#import <WebKit/WebKit.h>

    // 1.創(chuàng)建
    WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height )];
    // 2.創(chuàng)建請(qǐng)求
    NSMutableURLRequest *request =[NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.cnblogs.com/mddblog/"]];
    // 3.加載網(wǎng)頁(yè)
    [webView loadRequest:request];
    // 4.添加到界面
    [self.view addSubview:webView];

2. 一些實(shí)用函數(shù)

加載函數(shù)
新增了loadFileURL函數(shù),加載本地文件专普。

/// 加載函數(shù)
-(WKNavigation *)loadFileURL:(NSURL *)URL allowingReadAccessToURL:(NSURL *)readAccessURL
-(WKNavigation *)loadRequest:(NSURLRequest *)request;
-(WKNavigation *)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;
-(WKNavigation *)loadData:(NSData *)data MIMEType:(NSString *)MIMEType characterEncodingName:(NSString *)characterEncodingName baseURL:(NSURL *)baseURL;

以加載本地文件舉個(gè)栗子:

//模擬器調(diào)試加載mac本地文件
- (void)loadLocalFile {
    // 1.創(chuàng)建
    WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height )];
    // 2.創(chuàng)建url  userName:電腦用戶名
    NSURL *url = [NSURL fileURLWithPath:@"/Users/userName/Desktop/1.png"];
    // 3.加載文件
    [webView loadFileURL:url allowingReadAccessToURL:url];
    // 最后將webView添加到界面
    [self.view addSubview:webView];
}

網(wǎng)頁(yè)導(dǎo)航刷新相關(guān)函數(shù)

@property (nonatomic, readonly) BOOL canGoBack;
@property (nonatomic, readonly) BOOL canGoForward;
- (WKNavigation *)goBack;
- (WKNavigation *)goForward;
- (WKNavigation *)reload;
// 增加的函數(shù)  比較網(wǎng)絡(luò)數(shù)據(jù)是否有變化悯衬,沒(méi)有變化則使用緩存,否則從新請(qǐng)求檀夹。
- (WKNavigation *)reloadFromOrigin; 
// 增加的函數(shù)  可以跳轉(zhuǎn)到某個(gè)指定歷史頁(yè)面
- (WKNavigation *)goToBackForwardListItem:(WKBackForwardListItem *)item; 
- (void)stopLoading;
- 一些常用屬性
  • allowsBackForwardNavigationGestures:BOOL類型甚亭,是否允許左右劃手勢(shì)導(dǎo)航,默認(rèn)不允許
  • estimatedProgress:加載進(jìn)度击胜,取值范圍0~1
  • title:頁(yè)面title
  • .scrollView.scrollEnabled:是否允許上下滾動(dòng)亏狰,默認(rèn)允許
  • backForwardList:WKBackForwardList類型,訪問(wèn)歷史列表偶摔,可以通過(guò)前進(jìn)后退按鈕訪問(wèn)暇唾,或者通過(guò)goToBackForwardListItem函數(shù)跳到指定頁(yè)面

3.WKWebView中的代理方法

- WKNavigationDelegate

該代理提供的方法,可以用來(lái)追蹤加載過(guò)程(頁(yè)面開(kāi)始加載辰斋、加載完成策州、加載失敗)宫仗、決定是否執(zhí)行跳轉(zhuǎn)够挂。

// 頁(yè)面開(kāi)始加載時(shí)調(diào)用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation;
// 當(dāng)內(nèi)容開(kāi)始返回時(shí)調(diào)用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation;
// 頁(yè)面加載完成之后調(diào)用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation;
// 頁(yè)面加載失敗時(shí)調(diào)用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation;

頁(yè)面跳轉(zhuǎn)的代理方法有三種,分為(收到跳轉(zhuǎn)與決定是否跳轉(zhuǎn)兩種)

// 接收到服務(wù)器跳轉(zhuǎn)請(qǐng)求之后調(diào)用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation;
// 在收到響應(yīng)后藕夫,決定是否跳轉(zhuǎn)
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;
// 在發(fā)送請(qǐng)求之前孽糖,決定是否跳轉(zhuǎn)
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;

- WKUIDelegate

創(chuàng)建一個(gè)新的WKWebView

// 創(chuàng)建一個(gè)新的WebView
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures;

剩下三個(gè)代理方法全都是與界面彈出提示框相關(guān)的,針對(duì)于web界面的三種提示框(警告框毅贮、確認(rèn)框办悟、輸入框)分別對(duì)應(yīng)三種代理方法。

// 界面彈出警告框
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(void (^)())completionHandler;
// 界面彈出確認(rèn)框
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler;
// 界面彈出輸入框
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler;

- WKScriptMessageHandler

這個(gè)協(xié)議中包含一個(gè)必須實(shí)現(xiàn)的方法滩褥,這個(gè)方法是native與web端交互的關(guān)鍵病蛉,它可以直接將接收到的JS腳本轉(zhuǎn)為OC對(duì)象。

// 從web界面中接收到一個(gè)腳本時(shí)調(diào)用
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;

4.js交互

  • oc 調(diào)用js
NSString *scriptStr = @"showAlert('這里是oc調(diào)用js')";
[webView evaluateJavaScript:scriptStr completionHandler:^(id html, NSError * error) {
            if (error) {
                NSLog(@"%@",error);
                }
        }];
  • js調(diào)用OC
  • 先初始化WKWebView 并得遵循<WKScriptMessageHandler>協(xié)議
_wkWebView=[[WKWebView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[_wkWebView.configuration.userContentController addScriptMessageHandler:self name:@"getData"];
[self.view addSubview:_rwWebView];
NSURL *url=[[NSBundle mainBundle]URLForResource:@"index" withExtension:@"html"];
NSMutableURLRequest *tmpRequest=[[NSMutableURLRequest alloc] initWithURL:url];
[_wkWebView loadRequest:tmpRequest];

最重要的一句話是:

[_wkWebView.configuration.userContentController addScriptMessageHandler:self name:@"getData"];

//注冊(cè)一個(gè)name為getData的js方法

<WKScriptMessageHandler>協(xié)議的回調(diào)寫(xiě)法:

- (void)userContentController:(WKUserContentController *)userContentController
      didReceiveScriptMessage:(WKScriptMessage *)message{
   if([message.name  isEqualToString:@"getData"])
        
    {
        NSString * body = [message.body objectForKey:@"body"];
        //   在這里寫(xiě)oc 實(shí)現(xiàn)協(xié)議的native方法
        NSString *requestTmp = [NSString stringWithString:body];
        NSLog(@"%@", requestTmp);
}

在H5中需要執(zhí)行的JS代碼是:

if (window.webkit.messageHandlers) {window.webkit.messageHandlers.getData.postMessage({body: "這是一個(gè)消息"});}

postMessage()里面的參數(shù)可以是:Number, String, Date, Array,
Dictionary, and null.和OC對(duì)應(yīng)關(guān)系為:

JS OC
Number NSNumber
String NSString
Date NSDate
Array NSArray
Dictionary NSDictionary
null NSNull

html部分如下:

<!DOCTYPE html>
<html>
    <header>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <meta name="viewport" content="document.body.clientHeight, initial-scale=1.1, minimum-scale=1.1, maximum-scale=1.1, user-scalable=no">
        <script type="text/javascript">
       function showAlert(message){
            alert(message);
        }
       function btnClick() {
           if (window.webkit.messageHandlers){
             window.webkit.messageHandlers.getData.postMessage({body: "這是一個(gè)消息"});
           }else{
               getData('123','abc','456');}
            }
 }
        </script>
    </header>
    <body>
        <br/>
        <br/>
        <button type="button" onclick="btnClick()">快點(diǎn)我!</button>
    </body>
</html>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市铺然,隨后出現(xiàn)的幾起案子俗孝,更是在濱河造成了極大的恐慌,老刑警劉巖魄健,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件驹针,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡诀艰,警方通過(guò)查閱死者的電腦和手機(jī)柬甥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)其垄,“玉大人苛蒲,你說(shuō)我怎么就攤上這事÷搪” “怎么了臂外?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)喇颁。 經(jīng)常有香客問(wèn)我漏健,道長(zhǎng),這世上最難降的妖魔是什么橘霎? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任蔫浆,我火速辦了婚禮,結(jié)果婚禮上姐叁,老公的妹妹穿的比我還像新娘瓦盛。我一直安慰自己,他們只是感情好外潜,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布原环。 她就那樣靜靜地躺著,像睡著了一般处窥。 火紅的嫁衣襯著肌膚如雪嘱吗。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,631評(píng)論 1 305
  • 那天滔驾,我揣著相機(jī)與錄音谒麦,去河邊找鬼。 笑死嵌灰,一個(gè)胖子當(dāng)著我的面吹牛弄匕,可吹牛的內(nèi)容都是我干的颅悉。 我是一名探鬼主播沽瞭,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼剩瓶!你這毒婦竟也來(lái)了驹溃?” 一聲冷哼從身側(cè)響起城丧,我...
    開(kāi)封第一講書(shū)人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎豌鹤,沒(méi)想到半個(gè)月后亡哄,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡布疙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年蚊惯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片灵临。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡截型,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出儒溉,到底是詐尸還是另有隱情宦焦,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布顿涣,位于F島的核電站波闹,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏涛碑。R本人自食惡果不足惜精堕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蒲障。 院中可真熱鬧锄码,春花似錦、人聲如沸晌涕。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)余黎。三九已至重窟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惧财,已是汗流浹背巡扇。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留垮衷,地道東北人厅翔。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像搀突,于是被迫代替她去往敵國(guó)和親刀闷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容