Forked from skagedal/WorkaroundWebViewController.swift
Created
March 8, 2021 13:59
-
-
Save Carrione/5710d2e0123ea7e5d332678c7c0bb580 to your computer and use it in GitHub Desktop.
A simplified WKWebView view controller with workarounds for setting cookies.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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