[iOS][Swift] WebKit And WebView

Mở đầu

Chắc mỗi chúng ta đây, khi đã code iOS rồi thì chắc hẳn đều hơn 1 lần phải tạo các webview trong ứng dụng của mình để quản lý tốt hơn thay vì nhảy sang Safari để mở trang web đó. Với vài dòng code sau, việc đó thật dễ dàng

        let url = URL(string: "https://www.google.com")!
        let request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 20.0)
        self.webView.loadRequest(request)

Thậm chí vì nó quá ngắn nên chúng ta có thể làm màu thêm

extension WebViewViewController: UIWebViewDelegate {
    func webViewDidStartLoad(_ webView: UIWebView) {
        UIApplication.shared.isNetworkActivityIndicatorVisible = true
    }

    func webViewDidFinishLoad(_ webView: UIWebView) {
        UIApplication.shared.isNetworkActivityIndicatorVisible = false
    }

    func webView(_ webView: UIWebView, didFailLoadWithError error: Error) {
        UIApplication.shared.isNetworkActivityIndicatorVisible = false
    }
}

Rất dễ dàng, kết quả hiển thị ra đẹp mắt. Nhưng khi "tình cờ" mở Tab Debug Navigation thì

Screen Shot 2016-10-27 at 2.40.22 PM.png

Một ứng dụng hết sức cơ bản, nhưng để lại hậu quả khôn lường. Thử search xem nào. 12000 kết quả trong 0.25s. Có 1 vài giải pháp được đưa ra nhưng đều không giải quyết được vấn đề vốn đã thuộc về bản chất của UIWebView. Tuy vậy, trong 1 vài câu trả lời, ta dễ dàng bắt gặp những dòng suggest việc sử dụng WKWebView thay thế. Vậy WKWebView là gì, và dùng nó thì kết quả ra sao, chúng ta sẽ cùng test thử

WKWebView

Nhiều khi bạn đã biết thì WK ở trước chữ WKWebView chính là viết tắt của WebKit

WebKit là 1 framework khi mới chào đời đã mang trong mình một sứ mệnh lớn lao là làm việc như tôi đã nói ở phần mở đầu =)). Nếu muốn có thêm những thông tin chi tiết hơn về WebKit, bạn có thể đọc ở đây thay vì chờ tôi copy paste nó ra.

Có lẽ điều tuyệt vời đầu tiên mà WebKit mang lại chính là nó support từ iOS 8

Cùng thử sử dụng WebKit trong project nào

Khai báo

    override func loadView() {
        let webConfiguration = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.navigationDelegate = self
        self.view = webView
    }

rõ ràng việc khai báo của WKWebView có 1 vấn đề lớn. Nó ảnh hưởng rất nhiều tới việc custom webview của bạn. Hãy thử thay nó bằng 1 subView và chạy thử. Nó sẽ chẳng hiển thị gì hết 😄.

Tuy vậy, thông thường chúng ta luôn giành tặng 1 sự kính trọng lớn lao với nhu cầu xem website của người dùng qua việc để kích cỡ của webview càng lớn càng tốt. Vậy nên điều này cũng không phải là rào cản gì đó khiến chúng ta thấy khó chịu.

Và 1 điều đặc biệt nữa là WKWebView có tới 2 Delegate, và cái mà chúng ta thường dùng sẽ là navigationDelegate

extension WebKitViewController: WKNavigationDelegate {
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        showLoadingIndicator(false)
    }

    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        showLoadingIndicator(true)
    }

    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        showLoadingIndicator(false)
    }
}

Cùng chạy thử và cảm nhận ...

Screen Shot 2016-10-27 at 3.13.58 PM.png

Nhìn vào 2 biểu đồ trên, chắc hẳn các bạn cũng đã có những suy nghĩ riêng cho mình. Và có lẽ những suy nghĩ đó sẽ thay lời mà tôi muốn gửi tới các bạn

Kết

Dù chưa phải là hoàn hảo nhưng WKWebView cũng đã thể hiện mình là ứng viên tuyệt vời để thay thế cho UIWebView.

Cuối cùng xin gửi cho các bạn 1 số Tip (của thanh niên Shingo Fukuyama đã dày công sưu tầm và nghiên cứu) https://github.com/ShingoFukuyama/WKWebViewTips . Biết đâu trong đường đời tấp nập lại có khi các bạn cần đến nó.

P/s: source code lần này đơn giản quá nhưng tôi cũng xin dẫn link github cho bạn nào cần. Nhớ gắn star cho mình nhé 😄