This is most likely a new question as I have not seen any other question related.
I am trying to connect to a cybersource payment endpoint using WKWebview on SwiftUI
I get the error
I have tried to set cookie but still won't work
WebView
public struct HTMLView: UIViewRepresentable {
var url: String
var javascriptString: String
#Binding var webViewUIModel: UIModel
public init(url: String, javascriptString: String = "", webViewUIModel: Binding<UIModel>) {
self.url = url
self.javascriptString = javascriptString
self._webViewUIModel = webViewUIModel
}
public func makeUIView(context: Context) -> WKWebView {
// let webView = WKWebView()
let webConfiguration = WKWebViewConfiguration()
let store = WKWebsiteDataStore.default()
webConfiguration.websiteDataStore = store
webConfiguration.preferences.javaScriptCanOpenWindowsAutomatically = true
webConfiguration.defaultWebpagePreferences.allowsContentJavaScript = true
let webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.navigationDelegate = context.coordinator
webView.loadHTMLString(url, baseURL: nil)
return webView
}
public func updateUIView(_ uiView: WKWebView, context: Context) {
uiView.loadHTMLString(url, baseURL: nil)
}
public func makeCoordinator() -> WebViewCordinator {
.init(javascriptString: javascriptString) {
print("HTMLView: Start")
} didHaveError: { e in
print("HTMLView: Error")
} didFinish: {
print("HTMLView: Finish")
}
}
}
Cordinator
public class WebViewCordinator: NSObject, WKNavigationDelegate, WKUIDelegate {
var javascriptString: String
var didStart: () -> Void
var didHaveError: (Error) -> Void
var didFinish: () -> Void
public init(javascriptString: String = "", didStart: #escaping () -> Void, didHaveError: #escaping (Error) -> Void, didFinish: #escaping () -> Void) {
self.javascriptString = javascriptString
self.didStart = didStart
self.didHaveError = didHaveError
self.didFinish = didFinish
}
public func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: #escaping (WKNavigationResponsePolicy) -> Void) {
guard let response = navigationResponse.response as? HTTPURLResponse,
let url = navigationResponse.response.url else {
decisionHandler(.cancel)
return
}
if let headerFields = response.allHeaderFields as? [String: String] {
let cookies = HTTPCookie.cookies(withResponseHeaderFields: headerFields, for: url)
cookies.forEach { cookie in
print("Cookie \(cookie) \(cookie.domain)")
webView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie)
}
}
decisionHandler(.allow)
}
public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
print("Error \(error)")
didHaveError(error)
}
public func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
print("HTMLViewCOMMIT \( webView.url)")
}
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print( "HTMLViewFINISH \( String(describing: webView.url))")
webView.evaluateJavaScript("document.body.innerHTML") { value, error in
print("HTMLFinishValue \(value)")
print("Errot\(error)")
}
didFinish()
}
}
How can I resolve this?
Related
I have been on this for a week now. I am trying to make a POST request using WKWebview. This has been achieved on the android version seamlessly.
Replicating the same on iOS with SwiftUI has been a ton of complications.
I want the form to be submitted onload and redirect to the payment gate way web for authorization but it appears something is cancelling the request
I have tried to loadHTML through the webview but it did not work
public struct HTMLView: UIViewRepresentable {
var url: String
var javascriptString: String
#Binding var webViewUIModel: UIModel
public init(url: String, javascriptString: String = "", webViewUIModel: Binding<UIModel>) {
self.url = url
self.javascriptString = javascriptString
self._webViewUIModel = webViewUIModel
}
public func makeUIView(context: Context) -> WKWebView {
let webView = WKWebView()
webView.configuration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")
webView.navigationDelegate = context.coordinator
DispatchQueue.main.async {
webView.loadHTMLString(url, baseURL: nil)
}
return webView
}
public func updateUIView(_ uiView: WKWebView, context: Context) {
DispatchQueue.main.async {
uiView.loadHTMLString(url, baseURL: nil)
}
}
public func makeCoordinator() -> WebViewCordinator {
.init(javascriptString: javascriptString) {
print("HTMLView: Start")
} didHaveError: { e in
print("HTMLView: Error")
} didFinish: {
print("HTMLView: Finish")
}
}
}
public class WebViewCordinator: NSObject, WKNavigationDelegate {
var javascriptString: String
var didStart: () -> Void
var didHaveError: (Error) -> Void
var didFinish: () -> Void
public init(javascriptString: String = "",didStart: #escaping () -> Void, didHaveError: #escaping (Error) -> Void, didFinish: #escaping () -> Void) {
self.javascriptString = javascriptString
self.didStart = didStart
self.didHaveError = didHaveError
self.didFinish = didFinish
}
public func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) async {
print("HTMLViewREDIRECT \(await webView.url)")
}
public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
didHaveError(error)
}
public func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) async {
print("HTMLViewCOMMIT \(await webView.url)")
}
public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: #escaping (WKNavigationActionPolicy) -> Void) async {
print("HOST \(navigationAction.request)")
decisionHandler(.allow)
}
public func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse) async -> WKNavigationResponsePolicy {
let response = navigationResponse.response
print("HTMLViewResponse \(response)")
return .allow
}
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) async {
print( "HTMLViewFINISH \(await navigation)")
print( "HTMLViewFINISH \(await String(describing: webView.url))")
if !javascriptString.isEmpty {
await webView.evaluateJavaScript(javascriptString) { value, error in
print(self.javascriptString)
print(value)
print(error)
}
}
didFinish()
}
}
But I get this error 2023-02-06 16:49:22.994531+0000 TrialsProject[89459:6286324] [ServicesDaemonManager] interruptionHandler is called. -[FontServicesDaemonManager connection]_block_invoke at the end of the request.
I also tried using URLSession
var request = URLRequest(url: URL(string: url)!)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.allowsCellularAccess = true
request.httpMethod = "POST"
// let params =
request.httpBody = body.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { (data : Data?, response : URLResponse?, error : Error?) in
print("Response \(response)")
if data != nil {
if let returnString = String(data: data!, encoding: .utf8) {
print("Returned String \(returnString)")
}
}
}
task.resume()
But I get NSURLErrorDomain error code -999
What can I do to achieve a POST request with WKWebview?
I have a custom UIView with WKWebview.
And I found my webview delegate function webView didFinish、didReceive not work.
I print OK in webView didFinish but I found my local file already load.
What's wrong with my code?
Thanks.
public class CustomWebView: UIView{
#objc public var webview: WKWebView?
public var customDelegate: CustomDelegate?
override init(frame: CGRect) {
super.init(frame: frame)
loadXib()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
loadXib()
}
func loadXib(){
let bundle = Bundle(for: type(of: self))
let nib = UINib(nibName: "\(Self.self)", bundle: bundle)
let source = "var devicePlatform = 'iOS';"
let userScript = WKUserScript(source: source, injectionTime: .atDocumentStart, forMainFrameOnly: true)
let userContentController = WKUserContentController()
userContentController.add(self, name: "test")
userContentController.addUserScript(userScript)
let config = WKWebViewConfiguration()
config.userContentController = userContentController
if #available(iOS 9.0, *) {
config.applicationNameForUserAgent = "Custom_APP"
} else {
}
self.webview = WKWebView(frame: self.bounds, configuration: config)
guard let wView = self.webview else { return }
wView.uiDelegate = self as? WKUIDelegate
wView.navigationDelegate = self
wView.scrollView.bounces = false
wView.translatesAutoresizingMaskIntoConstraints = false
wView.allowsBackForwardNavigationGestures = true
wView.configuration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")
wView.evaluateJavaScript("navigator.userAgent") { (result, error) in
if let userAgent = result as? String, error == nil {
print("===) uA : \(userAgent)")
}
}
addSubview(wView)
}
}
extension CustomWebView {
public func start(){
guard let webview = self.webview else { return }
if Custom_Constants.IS_LOAD_LOCAL_HTML_FILE {
guard let url = URL(string: Custom_Constants.BASE_URL) else { return }
webview.loadFileURL(url, allowingReadAccessTo: url.deletingLastPathComponent())
} else {
guard let request = getRequest() else { return }
webview.load(request)
}
}
public func doHybridNativeRequest(request:NativeRequest){
self.webview?.evaluateJavaScript("native2Web(\(request.getParameter()))", completionHandler: nil)
}
func doActionType(response:WebResponse){
let actionName = response.name
if actionName == "backToApp" {
customDelegate?.goBackToApp?(webView: self, webResponse: response)
}
if actionName == "storeData" {
customDelegate?.storeData?(webView: self, webResponse: response)
}
if actionName == "retrieveData" {
customDelegate?.retrieveData?(webView: self, webResponse: response)
}
}
func filterWebResponse(message:WKScriptMessage, response:WebResponse){
if message.name == "test" {
doActionType(response: response)
}
}
}
extension CustomWebView{
fileprivate func getRequest() -> URLRequest? {
var request: URLRequest?
if let url = URL(string: "\(Custom_Constants.BASE_URL)") {
print("===) url here: \(url)")
request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 180)
}
return request
}
}
extension CustomWebView : UIWebViewDelegate{
public func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: #escaping () -> Void) {
}
public func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: #escaping (Bool) -> Void) {
let alertController = UIAlertController(title: nil, message: message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "YES", style: .default, handler: { (action) in
completionHandler(true)
}))
alertController.addAction(UIAlertAction(title: "NO", style: .default, handler: { (action) in
completionHandler(false)
}))
}
}
extension CustomWebView: WKNavigationDelegate{
public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
self.customDelegate?.errorHasOccurred?(error: error)
printLog("===) webView didFail....")
}
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("===) OK")
self.customDelegate?.webviewDidFinish?(webview: webView, navigation: navigation)
}
}
extension CustomWebView: WKScriptMessageHandler{
public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
guard let getDict = message.body as? Dictionary<String, Any> else{
return;
}
print("===) \(message.body)")
let response:WebResponse = WebResponse(parameter: getDict)
filterWebResponse(message: message, response: response)
}
}
I have WKWebView placed in List cell and want this cell to be autosized to height of content that was loaded into WKWebView. I have tried such code but it doesn't work
struct WebView: UIViewRepresentable {
let url: URL?
let html: String?
let didFail: (WKNavigation) -> Void
let didFinish: (WKNavigation) -> Void
#Binding var contentHeight : CGFloat
init(html: String, contentHeight: Binding<CGFloat> = .constant(0), didFail: #escaping (WKNavigation) -> Void = { _ in }, didFinish: #escaping (WKNavigation) -> Void = { _ in }) {
self.url = nil
self.html = html
self.didFinish = didFinish
self.didFail = didFail
self._contentHeight = contentHeight
}
init(url: URL, contentHeight: Binding<CGFloat> = .constant(0), didFail: #escaping (WKNavigation) -> Void = { _ in }, didFinish: #escaping (WKNavigation) -> Void = { _ in }) {
self.url = url
self.html = nil
self.didFinish = didFinish
self.didFail = didFail
self._contentHeight = contentHeight
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIView(context: Context) -> WKWebView {
let webView = WKWebView()
webView.navigationDelegate = context.coordinator
webView.uiDelegate = context.coordinator
if let url = url {
let request = URLRequest(url: url)
webView.load(request)
} else if let html = html {
webView.loadHTMLString(html, baseURL: nil)
}
return webView
}
func updateUIView(_ webView: WKWebView, context: Context) {
}
class Coordinator : NSObject, WKNavigationDelegate, WKUIDelegate {
private let parent: WebView
init(_ parent: WebView) {
self.parent = parent
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
parent.didFail(navigation)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("document.readyState", completionHandler: { (ready, error) in
if ready != nil {
webView.evaluateJavaScript("document.documentElement.scrollHeight", completionHandler: { (height, error) in
if let contentHeight = height as? CGFloat {
self.parent.contentHeight = contentHeight
}
})
}
})
parent.didFinish(navigation)
}
}
}
Even setting .frame(height: contentHeight) via #State does not work.
I'm a swift learner. I work with SwiftUI which is a struct, I have to implement a WKWebView and in that, a url is changing dynamically. I have to catch these changing urls, but solutions I have tried are not working.
For example: https://stackoverflow.com/a/48273950/10088243
I tried this code block but it is not working and it gives me some compiler errors:
import SwiftUI
import WebKit
struct ContentView: UIViewRepresentable, WKNavigationDelegate {
let request = URLRequest(url: URL(string: "https://apple.com")!)
func makeUIView(context: Context) -> WKWebView {
let preferences = WKPreferences()
preferences.javaScriptEnabled = true
preferences.javaScriptCanOpenWindowsAutomatically = true
let configuration = WKWebViewConfiguration()
configuration.preferences = preferences
let webView = WKWebView(frame: .zero, configuration: configuration)
webView.allowsBackForwardNavigationGestures = true
return webView
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
// 'override' can only be specified on class membe
if keyPath == #keyPath(WKWebView.url) {
print("### URL:", self.webView.url!)
}
if keyPath == #keyPath(WKWebView.estimatedProgress) {
// When page load finishes. Should work on each page reload.
if (self.webView.estimatedProgress == 1) {
print("### EP:", self.webView.estimatedProgress)
}
}
}
func updateUIView(_ uiView: WKWebView, context: Context) {
uiView.load(request)
}
func webViewDidFinishLoad(webView : WKWebView) {
print("Loaded: \(String(describing: webView.url))")
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("Loaded: \(String(describing: webView.url))")
//progressView.isHidden = true
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
//progressView.isHidden = false
print("Loaded: \(String(describing: webView.url))")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
I have a Non-class type 'ContentView' cannot conform to class protocol 'NSObjectProtocol' error at line struct ContentView...
You can simply create a ObservableObject model class of webview with the name "WebViewModel" like
class WebViewModel: ObservableObject {
#Published var link: String
#Published var didFinishLoading: Bool = false
init (link: String) {
self.link = link
}
}
and also import
import WebKit
import Combine
and then copy this code snippets
struct SwiftUIWebView: UIViewRepresentable {
#ObservedObject var viewModel: WebViewModel
let webView = WKWebView()
func makeUIView(context: UIViewRepresentableContext<SwiftUIWebView>) -> WKWebView {
self.webView.navigationDelegate = context.coordinator
if let url = URL(string: viewModel.link) {
self.webView.load(URLRequest(url: url))
}
return self.webView
}
func updateUIView(_ uiView: WKWebView, context: UIViewRepresentableContext<SwiftUIWebView>) {
return
}
class Coordinator: NSObject, WKNavigationDelegate {
private var viewModel: WebViewModel
init(_ viewModel: WebViewModel) {
self.viewModel = viewModel
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
//print("WebView: navigation finished")
self.viewModel.didFinishLoading = true
}
}
func makeCoordinator() -> SwiftUIWebView.Coordinator {
Coordinator(viewModel)
}
}
struct SwiftUIWebView_Previews: PreviewProvider {
static var previews: some View {
SwiftUIWebView(viewModel: WebViewModel(link: "https://google.com"))
//WebView(request: URLRequest(url: URL(string: "https://www.apple.com")!))
}
}
and in you view
struct AnyView: View {
#ObservedObject var model = WebViewModel(link: "https://www.wikipedia.org/")
var body: some View {
NavigationView {
SwiftUIWebView(viewModel: model)
if model.didFinishLoading {
//do your stuff
}
}
}}
so in this way you can get the others delegates response.
you use this to delegates of WKNavigationProtocol to perform(e.g to allow or cancel URL Loading) your action
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: #escaping (WKNavigationActionPolicy) -> Void) {
if let host = navigationAction.request.url?.host {
if host.contains("facebook.com") {
decisionHandler(.cancel)
return
}
}
decisionHandler(.allow)
}
Use the following delegate function of WKWebView:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: #escaping (WKNavigationActionPolicy) -> Void) {
// Suppose you don't want your user to go a restricted site
if let host = navigationAction.request.url?.host {
if host == "restricted.com" {
decisionHandler(.cancel)
return
}
}
decisionHandler(.allow)
}
You can read this article from Medium which shows a better way of intercepting every network call or Url changing and obtaining upcoming Url related data. It also shows how to implement WebView in SwiftUI, interfacing with JavaScript functions and loading a local .html file from iOS project
Simple, Just use this delegate method
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print(webView.url?.absoluteString)
}
You can use key/value observation to detect changes to the url property of the WKWebView.
Here is a simple example of wrapping a WKWebView in a UIViewRepresentable.
Note that because we are modifying a property, the UIViewRepresentable is a final class rather than a struct.
import Combine
import SwiftUI
import WebKit
final class WebView: UIViewRepresentable {
#Published var url: URL? = nil {
didSet {
if url != nil {
willChange.send(url)
}
}
}
private let view = WKWebView()
private var urlChangedObservation: NSKeyValueObservation?
private let willChange = PassthroughSubject<URL?, Never>()
func makeUIView(context: Context) -> WKWebView {
return makeWebView()
}
func updateUIView(_ uiView: WKWebView, context: Context) {
}
func display(_ html: String) {
self.view.loadHTMLString(html, baseURL: nil)
}
public func load(_ url: String) -> WebView {
let link = URL(string: url)!
let request = URLRequest(url: link)
self.view.load(request)
return self
}
func makeWebView() -> WKWebView {
self.urlChangedObservation = self.view.observe(\WKWebView.url, options: .new) { view, change in
if let url = view.url {
self.url = url
}
}
return self.view
}
}
You can then listen to the url modified notification in the onReceive() of the container holding the WebView:
.onReceive(self.webview.$url) { url in
if let url = url {
}
}
I came here trying a fast way to get a working sample in SwiftUI to get an HTML response from an web auth service. (in the specific the new DropBox awful auth schema using an URI... we do no see this details, but call-backs and code should be explanatory enough. (JSOn comes from my web server specified in URI) )
in our Swift UI part:
struct ContentView: View {
#State private var showingSheet = false
private var webCallBack: WebCallBack = nil
let webView = WKWebView(frame: .zero)
#State private var auth_code = ""
var body: some View {
VStack{
Text("\(auth_code)")
.font(.system(size: 50))
Button("Show Auth web form") {
self.showingSheet = true
}
.sheet(isPresented: $showingSheet) {
WebView( webView: webView, webCallBack: { (d: Dict?) in
print("\n", d)
auth_code = (d?["auth_code"] as? String) ?? "!!"
showingSheet = false
} )
}
}
}
}
Our implementation:
typealias WebCallBack = ( (Dict?)->() )?
class MyWKDelegate: NSObject, WKNavigationDelegate{
private var webCallBack : WebCallBack = nil
init(webCallBack: WebCallBack) {
self.webCallBack = webCallBack
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("End loading")
webView.evaluateJavaScript("document.body.innerHTML", completionHandler: { result, error in
if let html = result as? String {
//print(html)
// we are here also at first call, i.e. web view with user / password. Custiomize as needed.
if let d = dictFromJSONWith(string: html){
//print(d)
self.webCallBack?(d)
}
}
})
}
}
struct WebView: UIViewRepresentable {
let webView: WKWebView
let delegate: MyWKDelegate
internal init(webView: WKWebView, webCallBack: WebCallBack) {
self.webView = webView
self.delegate = MyWKDelegate(webCallBack: webCallBack)
webView.navigationDelegate = delegate
let urlStr = DB_URL.replacingOccurrences(of: "APP_KEY", with: APP_KEY).replacingOccurrences(of: "REDIRECT_URI", with: REDIRECT_URI)
print(urlStr)
if let url = URL(string: urlStr){
webView.load(URLRequest(url: url))
}
}
func makeUIView(context: Context) -> WKWebView {
return webView
}
func updateUIView(_ uiView: WKWebView, context: Context) { }
}
Some accessory code to make life easier:
typealias Dict = [String : Any]
typealias Dicts = [Dict]
func dictFromJSONWith(data: Data?)->Dict? {
guard let data = data else {
return nil
}
if let dict = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions() ){
return dict as? Dict
}
return nil
}
func dictFromJSONWith(string: String?)->Dict?{
guard let data = string?.data(using: .utf8) else{
return nil
}
return dictFromJSONWith(data: data)
}
I have found a very good solution to my question. I will post it here. Maybe someone wants to see it and might be useful to them.
observe.observation = uiView.observe(\WKWebView.url, options: .new) { view, change in
if let url = view.url {
// do something with your url
}
}
I'm not able to get cookies from this website - "https://bødekontrol.dk"
I'm using Xcode 9.4.1 and iOS 11.
I have followed below code,
import UIKit
import WebKit
class ViewController: UIViewController {
var urlString = "https://bødekontrol.dk"
var webView: WKWebView!
fileprivate var webViewIsInited = false
override func viewWillLayoutSubviews() {
if !webViewIsInited {
webViewIsInited = true
if webView == nil {
webView = WKWebView(frame: UIScreen.main.bounds, configuration: WKWebViewConfiguration())
}
view.addSubview(webView)
webView.navigationDelegate = self
webView.uiDelegate = self
webView.loadUrl(string: urlString)
}
}
}
extension ViewController: WKNavigationDelegate {
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: #escaping (WKNavigationResponsePolicy) -> Void) {
decisionHandler(.allow)
if let httpResponse = navigationResponse.response as? HTTPURLResponse {
if let headers = httpResponse.allHeaderFields as? [String: String], let url = httpResponse.url {
let cookies = HTTPCookie.cookies(withResponseHeaderFields: headers, for: url)
for cookie in cookies {
print(cookie.description)
print("found cookie " + cookie.name + " " + cookie.value)
}
}
}
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("didFinish navigation")
}
}
extension ViewController: WKUIDelegate {
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
if navigationAction.targetFrame == nil {
let vc = ViewController()
vc.urlString = navigationAction.request.url?.absoluteString ?? "http://google.com"
vc.view.frame = UIScreen.main.bounds
vc.webView = WKWebView(frame: UIScreen.main.bounds, configuration: configuration)
navigationController?.pushViewController(vc, animated: false)
return vc.webView
}
return nil
}
}
extension WKWebView {
func loadUrl(string: String) {
if let encoded = string.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
let url = URL(string: encoded)
{
if self.url?.host == url.host {
self.reload()
} else {
load(URLRequest(url: url))
}
}
}
}
Implement this protocol WKHTTPCookieStoreObserver and check function of this protocol.
cookiesDidChange