Photo by Daniel Korpai on Unsplash
What is Webview?
Webview 其實就是一個精簡的瀏覽器,透過渲染引擎(Webkit)呈現網頁內容,中文又翻作「網頁視圖」。
和我們所熟悉的瀏覽器(例如:iOS / Safari 和 Android / Chrome)相比,最大差異在於,外觀介面沒有網址列、功能鍵等功能。
透過 Webview 實現的混合模式開發(Hyprid APP),相較於原生開發(Native APP),具備跨平台開發、開發效率高、降低成本、可離線執行等優點;然而,也須考量效能性、安全性與兼容性等問題。
iOS APP 顯示網頁的三種方式
iOS SDK 提供三種方式,讓開發者用來顯示網頁內容:
透過 UIApplication 外開網頁視窗
UIApplication.shared.open
是 Swift 中的一個 API,功能是可暫時離開當前 APP,開啟指定的 URL。
import SwiftUI
struct ContentView: View {
var body: some View {
Button(action: {
let url = URL(string: "https://heidiliu2020.github.io/")!
UIApplication.shared.open(url)
}) {
Text("點我前往連結")
}
}
}
WKWebView
和 Android 的 Webview 元件類似,iOS 同樣有 Webview 能用來顯示網頁內容。
而在 iOS 的 WebView 分為 UIWebView 和 iOS 8+ 新增的 WKWebView 兩種類型。
WebKit 框架中的 WKWebView 相較於前者,在於性能與穩定性的提升,具備 Nitro JavaScript 引擎的等優點。並透過 UIViewRepresentable
協定包裝 View,顯示特定的網頁內容。
import SwiftUI
import WebKit
struct WebView: UIViewRepresentable {
func makeUIView(context: Context) -> some UIView {
// return UIView object
}
func updateUIView(_ uiView: some UIView, context: Context) {
// update UIView
}
}
使用上需注意 WKWebView 沒有內建的 Back & Forward 按鍵,若需提供返回歷史頁面等功能,必須自行開發一個自訂的網頁瀏覽器。
SFSafariViewController
相較於 WKWebView 的限制,iOS 9 中導入的控制器 SFSafariViewController,能使用與 Safari 瀏覽器相同的功能,例如切換上下頁。
方法是透過 UIViewControllerRepresentable
協定定義 SwiftUI view 型別,將 SFSafariViewController 包裝成 SwiftUI view,即可顯示網頁內容。
import SwiftUI
import SafariServices
struct SafariView: UIViewControllerRepresentable {
// TODO...
}
實戰練習
Step1. 環境架設:安裝 XCode
首先進入官網下載頁面,登入後選擇要下載 XCode 版本。
不同版本的 XCode,在使用上須考慮開發環境、APP 套件與 iOS 版本相容性,若需要安裝特定版本的 XCode,可參考這篇文章:如何手動快速下載不同版本的Xcode - Poy Chang。
Step2. 建立新專案
運行 XCode 後,點擊「Create a new Xcode project」建立新專案。
接著點選 APP 建立專案範本,內建範本有預設程式碼,能夠協助快速開發:
Step3. 利用 UIViewRepresentable 協定調用 WKWebView
接著透過 UIViewRepresentable
協定包裝 View,顯示指定的網頁內容:
- ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
WebView(url: URL(string: "https://heidiliu2020.github.io/")!)
.edgesIgnoringSafeArea(.all)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
- SwiftUIView.swift
import SwiftUI
import WebKit
struct WebView: UIViewRepresentable {
let url: URL
func makeUIView(context: Context) -> WKWebView {
let wkwebView = WKWebView()
wkwebView.load(URLRequest(url: url))
return wkwebView
}
func updateUIView(_ uiView: WKWebView, context: Context) {
}
}
Step4. Building and running an app
最後是運行 APP 驗證結果,點選上方的開始鍵執行 Building,點開右側的選單可選擇要運行的裝置版本,或是透過傳輸線連接在實體機上進行測試。
小結
同樣是因為專案上的測試需求,沒想到這回又再次把 Xcode 安裝回電腦中,也許因為過去曾稍微接觸過一點,這回相對沒那麼迷惘。
能夠直接把 APP Build 到實體手機測試,和透過 XCode 模擬器終究還是有很大區別,雖然要實際上架到 App Store 需要課金,但以現階段而言也已經很夠用了。回顧過去所接觸的知識,似乎明白儘管當初一知半解,只要再多經歷幾次也能夠好好運用這些技術了。
Reference
- 使用 UIViewRepresentable 協定 讓你輕鬆建立 SwiftUI TextView
- 利用 UIViewControllerRepresentable 協定 在 SwiftUI 存取相簿並使用相機