首先我們需要創一個WKWebView(iOS 8.0+),來呈現我們的網頁內容:
mWebView = WKWebView(frame: self.view.frame)
if let mWebView = mWebView {
mWebView.navigationDelegate = self
mWebView.load(request)
self.view.addSubview(mWebView)
}
第一行先指定我們的WkWebView的大小,接下來指定WKNavigationDelegate為目前的ViewContrller,
之後再載入我們希望的URL,並把我們創造出來的WkWebView加到目前的ViewContrller上.
載入網頁在正常情況下會成功,但總有某些狀況會導致失敗,這時候我們必須讓我們的ViewContrller去實作WKNavigationDelegate來接收成功或失敗的system callback,詳細程式碼如下:
extension WebViewController: WKNavigationDelegate {
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
print(error.localizedDescription)
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
print("Strat to load")
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("finish to load")
}
}
didFailProvisionalNavigation這個system callback執行到的時候,表示我們載入網頁失敗,這時候我們應該跳出對話框提示使用者暫時離開畫面或是重新嘗試載入網頁.
didStartProvisionalNavigation這個system callback執行到的時候,表示我們載入網頁成功,網頁會慢慢顯示出來
didFinish這個system callback執行到的時候,表示我們網頁載入完成,此時應該能看到完整的網頁畫面
以下為完整的範例程式碼:
import UIKit
import WebKit
class WebViewController: UIViewController {
var mWebView: WKWebView? = nil
override func viewDidLoad() {
super.viewDidLoad()
let url = "https://www.google.com.tw/"
loadURL(urlString: url)
}
private func loadURL(urlString: String) {
let url = URL(string: urlString)
if let url = url {
let request = URLRequest(url: url)
// init and load request in webview.
mWebView = WKWebView(frame: self.view.frame)
if let mWebView = mWebView {
mWebView.navigationDelegate = self
mWebView.load(request)
self.view.addSubview(mWebView)
self.view.sendSubviewToBack(mWebView)
}
}
}
}
extension WebViewController: WKNavigationDelegate {
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
print(error.localizedDescription)
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
print("Strat to load")
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("finish to load")
}
}
IOS的WKWebView提供了兩個function goBack() 和 goForward(),只要呼叫這兩個function,我們就能夠實現如同瀏覽器的回到上一頁與到下一頁的功能,為此我們新增了兩個button,並在這兩個button的@IBAction function內去加入以下的code:
@IBAction func backAction(_ sender: UIButton) {
if mWebView?.goBack() == nil {
print("No more page to back")
}
}
@IBAction func forwardAction(_ sender: UIButton) {
if mWebView?.goForward() == nil {
print("No more page to forward")
}
}
呼叫 goBack() 和 **goForward()**外,我們還加上了null的判斷,因為IOS很貼心的為我們處理當沒有上一頁可以回去及沒有下一頁可以去的狀況,當發生前述狀況時,就會回傳null.我們當然可以利用 goBack() 和 **goForward()**這兩個function是否回傳null來決定要enable或disable back button或forward button,但是因為WKWebView提供了兩個屬性 canGoForward 和 canGoBack ,所以我們只要在每次載入新的網頁時(即 func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) 中),去加入以下判斷就好:
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("finish to load")
if let webView = mWebView {
mForwardBtn.isEnabled = webView.canGoForward
mBackBtn.isEnabled = webView.canGoBack
}
}
這樣我們就能夠集中管理按鈕的enable或disalbe狀態,不用分散在兩個Action function裡面
你在點擊某些網頁連結的時候,有可能無法正常載入,有一種情況是因為 Security 的關係,你如果是在debug mode下,你會看到 didFailProvisionalNavigation 被執行到,且印出以下錯誤訊息:
The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.
官網的描述如下:
Starting in iOS 9.0 and macOS v10.11, App Transport Security (ATS) is enabled by default for connections created by URLSession. ATS requires the use of best practice secure protocols in HTTPS.
ref: https://developer.apple.com/documentation/foundation/urlerror/2865492-apptransportsecurityrequiressecu
簡單來說 iOS 9.0 和 macOS v10.11以後,所有的連線預設都要是 HTTPS 才行.可是還是有很多網頁不支援 HTTPS 連線,那怎麼辦呢? 我們可以在info.plist檔中去加入以下的key value來幫助我們解決這個問題.
更多關於App Transport Security的設定可參考以下連結:
https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW33
https://github.com/tgnivekucn/WKWebView1
ref:
https://developer.apple.com/documentation/webkit/wkwebview