Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Carrione/5710d2e0123ea7e5d332678c7c0bb580 to your computer and use it in GitHub Desktop.
Save Carrione/5710d2e0123ea7e5d332678c7c0bb580 to your computer and use it in GitHub Desktop.
A simplified WKWebView view controller with workarounds for setting cookies.
import UIKit
import WebKit
class WorkaroundWebViewController: UIViewController, WKNavigationDelegate {
let request: URLRequest
private let websiteDataStore = WKWebsiteDataStore.default()
private var webView: WKWebView!
private var initialDummyNavigation: WKNavigation?
init(request: URLRequest) {
self.request = request
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }
override func viewDidLoad() {
super.viewDidLoad()
configureWebView()
}
private func configureWebView() {
let configuration = WKWebViewConfiguration()
configuration.websiteDataStore = websiteDataStore
webView = WKWebView(frame: .zero, configuration: configuration)
webView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(self.webView)
// We pin the web view to the safe area because some pages break otherwise.
NSLayoutConstraint.activate([
view.safeAreaLayoutGuide.leftAnchor.constraint(equalTo: webView.leftAnchor),
view.safeAreaLayoutGuide.rightAnchor.constraint(equalTo: webView.rightAnchor),
view.safeAreaLayoutGuide.topAnchor.constraint(equalTo: webView.topAnchor),
view.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: webView.bottomAnchor)
])
webView.navigationDelegate = self
initialDummyNavigation = webView.loadHTMLString("", baseURL: nil)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
if navigation == initialDummyNavigation {
initialDummyNavigation = nil
setCookiesAndLoadRequest()
}
}
private func setCookiesAndLoadRequest() {
let cookies = HTTPCookieStorage.shared.cookies ?? []
websiteDataStore.httpCookieStore.setCookies(cookies) {
self.loadRequest()
}
}
private func loadRequest() {
webView.load(request)
}
// Errors
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
showAlert(for: error)
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
showAlert(for: error)
}
private func showAlert(for error: Error) {
let alert = UIAlertController(title: "Error", message: "\(error)", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(alert, animated: true, completion: nil)
}
}
extension WKHTTPCookieStore {
func setCookies(_ cookies: [HTTPCookie], completion: (() -> Void)?) {
let group = DispatchGroup()
for cookie in cookies {
group.enter()
setCookie(cookie, completionHandler: {
group.leave()
})
}
group.notify(queue: .main) {
completion?()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment