错误域= WebKitErrorDomain代码= 102;帧加载中断。 iOS wkwebview wknavigationdelegate

发布于 2025-01-30 18:07:21 字数 9564 浏览 4 评论 0原文

我正在研究一个将显示网站的应用程序。但是,在将网站加载到应用程序中时,我会遇到错误。我在Android上的工作也很好。

错误:

WebPageProxy :: didfailProvisionalloAdforframe:frameId = 3,domain = webkiterrordomain,代码= 102错误域= webkiterrordomain代码= 102 “中断框架负载” userInfo = {_ wkrecoveryAttempterErry​​key =< wkreloadframeRareRorreCoveryAtteTempter: 0x600001922120>,nserrorfailingurlstringkey = https://site.site.site/login, nserrorfailingurlkey = https://site.site.site/login, nslocalizedDescription =框架负载中断}失败的临时性 导航

我的代码:

//  ViewController.swift
import UIKit
import WebKit
import SafariServices
import PushNotifications

class ViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandler {

    let pushNotifications = PushNotifications.shared
    var webView: WKWebView!
    var manifest = WebAppManifest.shared

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage){

        if let objStr = message.body as? String {

            var arr = [" "," "]

            if objStr.contains(";") {

                arr = objStr.components(separatedBy: ";")

            }

            let tokenProvider = BeamsTokenProvider(authURL: "https://site.site/beams/token") { () -> (AuthData) in

                let headers : [String: String] = [:]

                var queryParams : [String: String] = [:]

                if objStr.contains(";") {

                    queryParams = ["api_token":arr[1]]

                }

                return AuthData(headers: headers, queryParams: queryParams)

            }

            

            if objStr.contains(";") {

                self.pushNotifications.setUserId(arr[0], tokenProvider: tokenProvider, completion: { error in

                    guard error == nil else {

                        print(error.debugDescription)

                        return

                    }

                    print("Succesfully authenticated with Pusher Beams")

                })

            } else {

                self.pushNotifications.setUserId(objStr, tokenProvider: tokenProvider, completion: { error in

                    guard error == nil else {

                        print(error.debugDescription)

                        return

                    }

                    print("Succesfully authenticated with Pusher Beams")

                })

            }

        }

    }

    override func viewDidLoad() {

        super.viewDidLoad()

        let contentcontroller = WKUserContentController()

        contentcontroller.add(self, name: "callbackHandler")

        let config = WKWebViewConfiguration()

        config.userContentController = contentcontroller

        // Set-up the UI

        self.view.backgroundColor = UIColor(fromHex: manifest.theme_color)

        // Creates the web view engine

        webView = WKWebView()

        view.addSubview(webView)

        webView.navigationDelegate = self

        // Display attribute

        var guide: AnyObject = self.view.safeAreaLayoutGuide

        if manifest.display == "fullscreen" {

            guide = self.view

            webView.scrollView.contentInsetAdjustmentBehavior = .always

        }

        // Make the Web View take the whole screen

        webView.translatesAutoresizingMaskIntoConstraints = false

        webView.topAnchor.constraint(equalTo: guide.topAnchor).isActive = true

        webView.rightAnchor.constraint(equalTo: guide.rightAnchor).isActive = true

        webView.leftAnchor.constraint(equalTo: guide.leftAnchor).isActive = true

        webView.bottomAnchor.constraint(equalTo: guide.bottomAnchor).isActive = true

        // It will enable navigation gestures on the web view

        webView.allowsBackForwardNavigationGestures = true

        let url = URL(string: "https://" + manifest.origin + manifest.start_url)!

        print(pushNotifications.getDeviceInterests())

        webView.load(URLRequest(url: url))

    }

    override var supportedInterfaceOrientations : UIInterfaceOrientationMask {

        get {

            switch manifest.orientation {

            case "landscape":

                return UIInterfaceOrientationMask.landscape

            case "portrait":

                return UIInterfaceOrientationMask.portrait

            default:

                return UIInterfaceOrientationMask.all

            }

        }

        set { self.supportedInterfaceOrientations = newValue }

    }

    override var prefersStatusBarHidden: Bool {

        return manifest.display == "fullscreen"

    }

    override var preferredStatusBarStyle: UIStatusBarStyle {

        return UIColor(fromHex: manifest.theme_color).isDark() ? .lightContent : .darkContent

    }

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {

        view.setNeedsLayout()

    }

    // MARK: loadWebPage function

    func loadWebPage(url: URL)  {

        var components = URLComponents(url: url, resolvingAgainstBaseURL: false)

    components?.query = nil

        // If already has a query then append a param

        // otherwise create a new one

        if let query = url.query {

            // If isFromMobile param already exists jsut reassign the existing query

            if query.contains("source=TWA&platform=iOS") {

                components?.query = query

            } else {

                 components?.query = query + "&source=TWA&platform=iOS"

            }

        } else {

            components?.query = "source=TWA&platform=iOS"

        }

        print(components!.url!)

        let customRequest = URLRequest(url: components!.url!)

        webView!.load(customRequest)

    }

    // MARK: NavigationAction handler

    // Defines if it should navigate to a new URL

    // Logic to check if the destination URL is in the scope

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

        print(navigationAction.request.url?.absoluteURL)

        if let host = navigationAction.request.url?.host,

           let path = navigationAction.request.url?.path{

            if host.contains(manifest.origin) &&

                path.starts(with: manifest.scope){

                let query = navigationAction.request.url?.query

                if  query != nil{

                    print("two")

                    // MARK: Pusher clear state

                    if path.contains("logout") || path.contains("login") {

                        pushNotifications.clearAllState {

                            print("Cleared all state!")

                        }

                    }

                    decisionHandler(.allow)

                } else {

                    print("one")

                    loadWebPage(url: navigationAction.request.url!)

                    decisionHandler(.cancel)

                }

                return

            } else {

                print("wrong")

                // Destination URL is out of the scope

                if navigationAction.request.url?.scheme == "http" ||

                    navigationAction.request.url?.scheme == "https" {

                    // Opens an In-App browser

                    decisionHandler(.cancel)

                    let safariVC = SFSafariViewController(url: navigationAction.request.url!)

                    safariVC.preferredBarTintColor = UIColor(fromHex: manifest.theme_color)

                    safariVC.preferredControlTintColor =

                        UIColor(fromHex: manifest.theme_color).isDark() ? UIColor.white : UIColor.black

                    present(safariVC, animated: true)

                } else {

                    // It looks like a different protocol

                    // We ask the OS to open it

                    UIApplication.shared.open(navigationAction.request.url!)

                }

            }

        } else {

            decisionHandler(.cancel)

        }

    }

    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse,

                 decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {

        print("error")

        if let response = navigationResponse.response as? HTTPURLResponse {

            if response.statusCode >= 400 {

                print("400 error")

                handleError()

            }

        }

        decisionHandler(.allow)

    }

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

        print(error, "Failed Navigation")

        handleError()

    }

    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {

        print(error, "Failed Provisinal Navigation")

        handleError()

    }

    // Error handling in case the content of the PWA can't be loaded

    func handleError() {

        webView.loadHTMLString("<h1>:(</h1>", baseURL: nil)

        let alert = UIAlertController(title: "Error", message: "There was a problem loading the App from the Internet. Please check your connection and try again", preferredStyle: .alert)

        alert.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: { (action) in

            exit(100)

        }))

        present(alert, animated: true)

    }

}

我已经制作了此类类型的多个应用程序,但从未弹出过此错误。关于如何解决此问题的任何建议?

I´m working on an app that will show a website. But I'm running into errors when loading the website in app. I´ts also working perfectly fine on android.

The error:

WebPageProxy::didFailProvisionalLoadForFrame: frameID = 3, domain =
WebKitErrorDomain, code = 102 Error Domain=WebKitErrorDomain Code=102
"Frame load interrupted"
UserInfo={_WKRecoveryAttempterErrorKey=<WKReloadFrameErrorRecoveryAttempter:
0x600001922120>, NSErrorFailingURLStringKey=https://site.site/login,
NSErrorFailingURLKey=https://site.site/login,
NSLocalizedDescription=Frame load interrupted} Failed Provisinal
Navigation

My code:

//  ViewController.swift
import UIKit
import WebKit
import SafariServices
import PushNotifications

class ViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandler {

    let pushNotifications = PushNotifications.shared
    var webView: WKWebView!
    var manifest = WebAppManifest.shared

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage){

        if let objStr = message.body as? String {

            var arr = [" "," "]

            if objStr.contains(";") {

                arr = objStr.components(separatedBy: ";")

            }

            let tokenProvider = BeamsTokenProvider(authURL: "https://site.site/beams/token") { () -> (AuthData) in

                let headers : [String: String] = [:]

                var queryParams : [String: String] = [:]

                if objStr.contains(";") {

                    queryParams = ["api_token":arr[1]]

                }

                return AuthData(headers: headers, queryParams: queryParams)

            }

            

            if objStr.contains(";") {

                self.pushNotifications.setUserId(arr[0], tokenProvider: tokenProvider, completion: { error in

                    guard error == nil else {

                        print(error.debugDescription)

                        return

                    }

                    print("Succesfully authenticated with Pusher Beams")

                })

            } else {

                self.pushNotifications.setUserId(objStr, tokenProvider: tokenProvider, completion: { error in

                    guard error == nil else {

                        print(error.debugDescription)

                        return

                    }

                    print("Succesfully authenticated with Pusher Beams")

                })

            }

        }

    }

    override func viewDidLoad() {

        super.viewDidLoad()

        let contentcontroller = WKUserContentController()

        contentcontroller.add(self, name: "callbackHandler")

        let config = WKWebViewConfiguration()

        config.userContentController = contentcontroller

        // Set-up the UI

        self.view.backgroundColor = UIColor(fromHex: manifest.theme_color)

        // Creates the web view engine

        webView = WKWebView()

        view.addSubview(webView)

        webView.navigationDelegate = self

        // Display attribute

        var guide: AnyObject = self.view.safeAreaLayoutGuide

        if manifest.display == "fullscreen" {

            guide = self.view

            webView.scrollView.contentInsetAdjustmentBehavior = .always

        }

        // Make the Web View take the whole screen

        webView.translatesAutoresizingMaskIntoConstraints = false

        webView.topAnchor.constraint(equalTo: guide.topAnchor).isActive = true

        webView.rightAnchor.constraint(equalTo: guide.rightAnchor).isActive = true

        webView.leftAnchor.constraint(equalTo: guide.leftAnchor).isActive = true

        webView.bottomAnchor.constraint(equalTo: guide.bottomAnchor).isActive = true

        // It will enable navigation gestures on the web view

        webView.allowsBackForwardNavigationGestures = true

        let url = URL(string: "https://" + manifest.origin + manifest.start_url)!

        print(pushNotifications.getDeviceInterests())

        webView.load(URLRequest(url: url))

    }

    override var supportedInterfaceOrientations : UIInterfaceOrientationMask {

        get {

            switch manifest.orientation {

            case "landscape":

                return UIInterfaceOrientationMask.landscape

            case "portrait":

                return UIInterfaceOrientationMask.portrait

            default:

                return UIInterfaceOrientationMask.all

            }

        }

        set { self.supportedInterfaceOrientations = newValue }

    }

    override var prefersStatusBarHidden: Bool {

        return manifest.display == "fullscreen"

    }

    override var preferredStatusBarStyle: UIStatusBarStyle {

        return UIColor(fromHex: manifest.theme_color).isDark() ? .lightContent : .darkContent

    }

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {

        view.setNeedsLayout()

    }

    // MARK: loadWebPage function

    func loadWebPage(url: URL)  {

        var components = URLComponents(url: url, resolvingAgainstBaseURL: false)

    components?.query = nil

        // If already has a query then append a param

        // otherwise create a new one

        if let query = url.query {

            // If isFromMobile param already exists jsut reassign the existing query

            if query.contains("source=TWA&platform=iOS") {

                components?.query = query

            } else {

                 components?.query = query + "&source=TWA&platform=iOS"

            }

        } else {

            components?.query = "source=TWA&platform=iOS"

        }

        print(components!.url!)

        let customRequest = URLRequest(url: components!.url!)

        webView!.load(customRequest)

    }

    // MARK: NavigationAction handler

    // Defines if it should navigate to a new URL

    // Logic to check if the destination URL is in the scope

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

        print(navigationAction.request.url?.absoluteURL)

        if let host = navigationAction.request.url?.host,

           let path = navigationAction.request.url?.path{

            if host.contains(manifest.origin) &&

                path.starts(with: manifest.scope){

                let query = navigationAction.request.url?.query

                if  query != nil{

                    print("two")

                    // MARK: Pusher clear state

                    if path.contains("logout") || path.contains("login") {

                        pushNotifications.clearAllState {

                            print("Cleared all state!")

                        }

                    }

                    decisionHandler(.allow)

                } else {

                    print("one")

                    loadWebPage(url: navigationAction.request.url!)

                    decisionHandler(.cancel)

                }

                return

            } else {

                print("wrong")

                // Destination URL is out of the scope

                if navigationAction.request.url?.scheme == "http" ||

                    navigationAction.request.url?.scheme == "https" {

                    // Opens an In-App browser

                    decisionHandler(.cancel)

                    let safariVC = SFSafariViewController(url: navigationAction.request.url!)

                    safariVC.preferredBarTintColor = UIColor(fromHex: manifest.theme_color)

                    safariVC.preferredControlTintColor =

                        UIColor(fromHex: manifest.theme_color).isDark() ? UIColor.white : UIColor.black

                    present(safariVC, animated: true)

                } else {

                    // It looks like a different protocol

                    // We ask the OS to open it

                    UIApplication.shared.open(navigationAction.request.url!)

                }

            }

        } else {

            decisionHandler(.cancel)

        }

    }

    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse,

                 decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {

        print("error")

        if let response = navigationResponse.response as? HTTPURLResponse {

            if response.statusCode >= 400 {

                print("400 error")

                handleError()

            }

        }

        decisionHandler(.allow)

    }

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

        print(error, "Failed Navigation")

        handleError()

    }

    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {

        print(error, "Failed Provisinal Navigation")

        handleError()

    }

    // Error handling in case the content of the PWA can't be loaded

    func handleError() {

        webView.loadHTMLString("<h1>:(</h1>", baseURL: nil)

        let alert = UIAlertController(title: "Error", message: "There was a problem loading the App from the Internet. Please check your connection and try again", preferredStyle: .alert)

        alert.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: { (action) in

            exit(100)

        }))

        present(alert, animated: true)

    }

}

I have already made multiple apps of this type of but never had this error pop up. Any suggestion on how to fix this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文