1. 程式人生 > >WKWebView和UIWebView及其四種互動

WKWebView和UIWebView及其四種互動

**

UIWebView

官方文件翻譯

**
繼承關係:NSObject→UIResponder→UIView-→UIWebView

遵循:NSCoding NSObject UIAppearance UIAppearanceContainer UICoordinateSpace UIDynamicItem UIScrollViewDelegate UITraitEnvironment

你可以使用UIWebView類嵌入網頁內容在您的應用程式。這樣做,您只需建立一個UIWebView物件,將它附加到一個視窗,併發送一個請求來載入網頁內容。你也可以使用這個類來搬回和網頁歷史的前進,你甚至可以以程式設計方式設定的一些網頁內容的性質。

注:

在iOS 8及以後的執行應用程式,建議您使用WKwebview代替使用UIWebView。此外,如果你使用不能執行的JavaScript檔案,應該設定WKpreferences屬性 javascriptenabled為NO。

使用loadhtmlstring:baseURL:開始載入本地HTML檔案,loadRequest的方法:開始載入的Web內容的方法。使用stopLoading方法停止載入,loading 屬性是去發現是否有一個Web檢視是在載入過程中。

如果你允許使用者通過網頁歷史向前向後移動了,那麼你可以使用goForward和goBack方法做完按鈕的動作。使用canGoBack和canGoForward屬性禁用的按鈕時當用戶不能在一個方向移動。

預設情況下,一個webview會自動將出現在網路內容中的電話號碼轉換為電話號碼。當電話連結被點選時,手機應用將進行撥號。設定detectsphonenumbers屬性為NO 關閉此預設行為。

當網頁內容顯示時,你也可以使用scalesPageToFit屬性去設定網頁內容的比例。此後,使用者可以使用手勢改變尺度。

如果你想跟蹤Web內容載入設定代表性物件符合UIWebviewdelegate協議等。

重點:
你不應該嵌入UIWebView或UITableView物件到UIScrollView物件裡。如果你這樣做,意外的行為可能會導致因為觸控事件的物件可以混淆和錯誤處理。
一般的處理方式是直接在html中呼叫JS或者CSS,或者是最近比較流行的query mobile ,都可以直接呼叫系統的API,執行操作。

WKWebView

蘋果在iOS8中加入的用來替代UIWebView的控制元件。比UIWebView載入塊一倍的控制元件,記憶體方面卻比它少一半,但是相對的快取處理方面會稍微差一點。

整理下優缺點如下:
優點:
將瀏覽器核心渲染程序提取出 App,由系統進行統一管理,這減少了相當一部分的效能損失。
js 可以直接使用已經事先注入 js runtime 的 js 介面給 Native 層傳值,不必再通過苦逼的 iframe 製造頁面重新整理再解析自定義協議的奇怪方式。
支援高達 60 fps 的滾動重新整理率,內建了手勢探測。

缺點:
WK對快取和Cookie操作沒有UIWebView那麼方便。(呼叫的API沒有那麼顯著的用途。)
WK從iOS8才開始支援,也就是說在我們同時對iOS7支援的情況下,如果為了減少程式碼量及適配等方面因素,一樣會選擇UIWebView。

鑑於 UIWebView的鐘愛,淺談一下其快取機制

1、NSURLRequestUseProtocolCachePolicy NSURLRequest預設的cache policy,使用Protocol協議定義。

2、NSURLRequestReloadIgnoringCacheData 忽略快取直接從原始地址下載。

3、NSURLRequestReturnCacheDataElseLoad 只有在cache中不存在data時才從原始地址下載。

4、NSURLRequestReturnCacheDataDontLoad 只使用cache資料,如果不存在cache,請求失敗;用於沒有建立網路連線離線模式;

5、NSURLRequestReloadIgnoringLocalAndRemoteCacheData:忽略本地和遠端的快取資料,直接從原始地址下載,與NSURLRequestReloadIgnoringCacheData類似。

6、NSURLRequestReloadRevalidatingCacheData:驗證本地資料與遠端資料是否相同,如果不同則下載遠端資料,否則使用本地資料。

**

OC與H5的互動

**
當然我們在用到webview的時候會經常用到互動類的,實際即為WEB端和iOS手勢的結合,而帶來的一些資料的交換。

方法一、用來監聽當前web的協議方法

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 

此方法用於,web載入新的網路請求,監聽並得到webview的一些資訊

方法二、呼叫JS執行語句,在點選之後直接執行對應JS語句。

另個就是直接呼叫JS語句(學一些比較基本的JS語句還是很有必要的)
[webview stringByEvaluatingJavaScriptFromString:@”JS方法”]; //新增到head標籤中
然後當前web就會直接執行那個JS方法

還有一種就是JS調OC的方法
其實和第一種類似,在html裡面約定好,你給傳一個方法名(其實只是約定的一個string)然後我再根據方法

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

來判斷是否呼叫了,然後直接執行相應的方法。

方法三、比較實用的H5呼叫OC自定義方法。無需使用代理方法**

其實還是有一種H5直接呼叫OC的方法的。此方法很好的解決了H5和iOS上架應用的互動問題.

現在要求web中遇到404的情況,直接在H5中判斷到然後呼叫OC自定義方法。執行操作。

//H5呼叫的OC方法
- (void)jsValue
{
    //獲取H5中的JS上下文
    JSContext *context = [webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

    //JS方法中約定的一個方法名
     NSString *overtime = @"logee";

    //執行H5呼叫的方法後,iOS執行的方法。執行方法名對應的程式碼塊。

    context[overtime] = ^() {

        NSURL *url = [[NSURL alloc]initWithString:URL_LOGIN];
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        [webview loadRequest:request];

        NSArray *args = [JSContext currentArguments];

        for (JSValue *jsVal in args) {
            NSLog(@"%[email protected]", jsVal);
        }

        JSValue *this = [JSContext currentThis];
        NSLog(@"jsValue:%@",this);
    };

    //執行H5呼叫的方法後,iOS執行的方法。
    context[@"overTime"] = ^(){
        NSURL *url = [[NSURL alloc]initWithString:@"https://www.baidu.com"];
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        [webview loadRequest:request];
    };

}

H5中的index.html程式碼部分

<html lang="en">  

    <head>  

         <meta charset="utf-8">  

          <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">  
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />      

            <meta name="description" content="">  

            <meta name="viewport" content="width=device-width; initial-scale=1.0">  
             <script type="text/javascript" src="index.js"></script>             


      </head>  

    <button id="hallo" onclick="buttonClick()"> 點選button</button>  

    </body>  

</html>  

我們在JS程式碼中要寫的index.js

點選Button執行的操作。

function buttonClick()  
{  
    overTime("hello world");  
}  

產生的效果就是點選Button,然後執行了OC程式碼塊

注意:最好不要使用以下程式碼獲取狀態碼
在使用過程中容易產生重複傳送表單。

#pragma mark -  
#pragma mark - UIWebView Delegate Methods  
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType  
{  
    static BOOL isRequestWeb = YES;  

    if (isRequestWeb) {  
        NSHTTPURLResponse *response = nil;  
          //重新發送了資料請求,重複表單。
        NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];  
        if (response.statusCode == 404) {  
            // code for 404  
            return NO;  
        } else if (response.statusCode == 403) {  
            // code for 403  
            return NO;  
        }  

        [webView loadData:data MIMEType:@"text/html" textEncodingName:nil baseURL:[request URL]];  

        isRequestWeb = NO;  
        return NO;  
    }  

    return YES;  
}  

方法四、 使用三方庫WebViewJavascriptBridge ,iOS 8之後使用WKwebview,所以也是也有很多使用的

一般我們都保留兩個版本,支援iOS 8以上,webview 基本就背放棄了,所以這樣也就簡單介紹下WKWebViewJavascriptBridge的使用。具體的demo可以下載閱讀。

下面是OC的程式碼也是他的官網demo

首先下載WKWebViewJavascriptBridge 匯入專案中,加入標頭檔案

import "WKWebViewJavascriptBridge.h"
  if (_bridge) { return; }

    WKWebView* webView = [[NSClassFromString(@"WKWebView") alloc] initWithFrame:self.view.bounds];
    webView.navigationDelegate = self;
    [self.view addSubview:webView];

//wk的類方法,相當於註冊,裡面就一個返回值預設false,呼叫後直接返回yes
    [WKWebViewJavascriptBridge enableLogging];

    //相當於將 _bridge物件繫結到這個webview中。
    _bridge = [WKWebViewJavascriptBridge bridgeForWebView:webView];

    //設定WKwebview的代理 WKNavigationDelegate ,看原檔案就知道了。
    [_bridge setWebViewDelegate:self];


    /**
     *  註冊回撥
     *
     *  @param data             JS傳給前端的資料
     *  @param responseCallback
     *
     *  @ testObjcCallback 就是handlerName,是和前端約定好的,
     *
     */
    [_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) {

        //objc  回撥的資料,也就是JS傳給objc的資料
        NSLog(@"JS傳送給objc的資料:%@", data);

         //回撥的響應,就是前端接收到資料後,然後可將有用的資料返回給JS
        responseCallback(@"需要回調給js的資料");
    }];
 //JS 給約定的js方法testJavascriptHandler" 傳送資料
    [_bridge callHandler:@"testJavascriptHandler" data:@{ @"foo":@"before ready" }];
// 此方法為了將data 資料放送給js 
- (void)callHandler:(id)sender {
    id data = @{ @"greetingFromObjC": @"Hi there, JS!" };
    [_bridge callHandler:@"testJavascriptHandler" data:data responseCallback:^(id response) {
        NSLog(@"testJavascriptHandler responded: %@", response);
    }];
}

相關推薦

WKWebViewUIWebView其四互動

** UIWebView 官方文件翻譯 ** 繼承關係:NSObject→UIResponder→UIView-→UIWebView 遵循:NSCoding NSObject UIAppearance UIAppearanceContainer U

WKWebViewUIWebView載入本地htmlJS互動各種坑解決辦法

因為蘋果的檔案機制,所有的資原始檔都相當於放在bundle的路徑裡,裡面不分任何資料夾路徑,所以我們在載入(js, css, png)等等的資原始檔的時候,不應該加上任何檔名,所以最好是把所有有關html的檔案都放在同一平級的資料夾 UIWebView 1.OC調JS

JS與OC互相呼叫的一百方法(包括WKWebViewUIWebView)

/** * 根據webView、navigationAction相關資訊決定這次跳轉是否可以繼續進行,這些資訊包含HTTP傳送請求,如頭部包含User-Agent,Accept,refer * 在傳送請求之前,決定是否跳轉的代理 * @param webView * @param naviga

談IO中的阻塞非阻塞,同步非同步IO模型

什麼是同步和非同步?        燒水,我們都是通過熱水壺來燒水的。在很久之前,科技還沒有這麼發達的時候,如果我們要燒水,需要把水壺放到火爐上,我們通過觀察水壺內的水的沸騰程度來判斷水有沒有燒開。隨著科技的發展,現在市面上的水壺都有了提醒功能,當我們把水壺插電

Activity的生命週期其四啟動模式

兩個Activity之間相互startActivity跳轉. Activity a–>Activity b 1.首先啟動Activity a的時候依次走onCreate –> onStart –> onResume 這三個方法一次執行完後

WKWebView UIWebView、網頁快取、網路請求快取

// //  ViewController.m //  WebView // //  Created by lambo on 2017/1/17. //  Copyright © 2017年 cn.lr. All rights reserved. //

WKWebViewUIWebView檢視訪問網頁html內容的方法

此貼用於記錄我在學習oc與js互動時,檢視訪問html的body標籤內內容的方法。 WKWebView: NSString *doc = @"document.body.outerHTML"

OOP 思想 設計原則 24設計模式

父類 分組 策略 結構 並且 實例 適配器模式 closed 不同的 oop思想:封裝、繼承、多態 把組件實現和接口分開,並且讓組件具有多態性 面向對象編程是一種解決軟件復用的設計和編程方法,這種方法把軟件中相近相似的操作邏輯和操作應用數據

談IO中的阻塞非阻塞,同步異步IO模型

狀態 阻塞io 舉例 最大的 data- str 被調用 當我 返回 什麽是同步和異步? 燒水,我們都是通過熱水壺來燒水的。在很久之前,科技還沒有這麽發達的時候,如果我們要燒水,需要把水壺放到火爐上,我們通過觀察水壺內的水的沸騰程度來判斷水有沒有燒開。隨著科

【小家Java】深入理解Java列舉型別(enum)7常見的用法(含EnumMapEnumSet)

相關閱讀 【小家java】java5新特性(簡述十大新特性) 重要一躍 【小家java】java6新特性(簡述十大新特性) 雞肋升級 【小家java】java7新特性(簡述八大新特性) 不溫不火 【小家java】java8新特性(簡述十大新特性) 飽受讚譽 【小家java】java9

淺談深拷貝淺拷貝實現方法

rgb bsp for ace onos 都是 UNC get con 討論深拷貝與淺拷貝之前,要先回顧一下值傳遞與引用傳遞: 值傳遞: var a = 10; var b = a; b++; //console.log(a,b)//a:10 b:11 引用傳遞: v

okHttp的基本使用2請求方式各方法的同步非同步實現

一、效果 二、佈局 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"

WKWebView /UIWebView以及cordova的互動 個人理解

公司使用WKWebView載入h5介面,使用cordova載入h5頁面,cordova使用的底層是UIWebView, cordova 使用CDVInvokedUrlCommand實現js調原生,使用CDVCommandDelegate實現原生調js以及傳值.   webview載

已知中序先序|後序,建立二叉樹方式遍歷

const int maxv= 10000+10; int n; int in_order[maxv],post_order[maxv],pre_order[maxv]; int lch[maxv],rch[maxv]; //左右子節點 int build1(int L1,

web3以太坊智慧合約互動,如何簽名廣播交易以及web3版本1.00.20的區別

一、web3.js介紹          web3.js是以太坊官方的Javascript API,可以幫助智慧合約開發者使用HTTP或者IPC與本地的或者遠端的以太坊節點互動。實際上就是web3.js是一個庫集合,允許您使用HTTP或IPC連線與本地或遠端以太它節點進行互

WIN8 與WIN7的64位32位 分別對Legacy BIOS+MBRUEFI+GPT兩啟動方式分割槽架構下的安裝可行性分析

微軟系統、相關產品官方映象下載:http://msdn.itellyou.cn/關於MBR、GPT、ESP、MSR、EFI、UEFI和WIN8中SECURE BOOT的基礎知識:1.MBR分割槽表:Master Boot Record,即硬碟主引導記錄分割槽表,只支援容量在 2.1TB 以下的硬碟,超過2

hadoop初識之三:搭建hadoop環境(配置HDFS,Yarnmapreduce 執行在yarn)上執行模式(本地模式,偽分散式分散式介)

--===============安裝jdk(解壓版)================== --root 使用者登入 --建立檔案層級目錄    /opt下分別 建 modules/softwares/datas/tools 資料夾 --檢視是否安裝jdk    rpm -

ios js與oc原生WKWebView方法注入互動傳值

    上篇文章中,我們整理了關於WKWebView的詳細使用,包含進度條、獲取web title等等內容,這篇文章我們整理下,專案中,我們可能使用到的oc 與 js 原生互動場景下的使用.如有興趣,

WKWebView詳解&WKWebVieWJS互動

開發App的過程中,常常會遇到在App內部載入網頁,通常用UIWebView載入。而這個自iOS2.0開始使用的Web容器一直是開發的心病:載入速度慢,佔用記憶體多,優化困難。如果載入網頁多,還可能因為過量佔用記憶體而給系統kill掉。各種優化的方法效果也不那麼明顯iOS8 以後,蘋果推出了新框架 W

wkwebview H5互動時的坑(一)

WKWebView 白屏問題(或者是說頁面載入有問題,出不來) 在使用微博viewjavascriptbridge 時 與到了一個這樣的問題:       在使用拍照或選擇相簿的時候,選完圖片後回到頁面來是就白屏了。 為什麼會出現這樣的問題:      因為拍照是高記憶