gpt4 book ai didi

swift - NSInternalInconsistencyException 完成处理程序传递给 webView :decidePolicyForNavigationAction:decisionHandle was not called

转载 作者:行者123 更新时间:2023-11-28 05:55:58 29 4
gpt4 key购买 nike

我在我们的一个 iOS 应用测试中遇到了问题。非常感谢任何解决问题的帮助!

测试代码:

    func testOpenExternalBrowser_for_valid_urls() {
// Given
let vc = MockDashboardViewController()
vc.openInternalBrowserCalled = false
vc.openExternalBrowserCalled = false
vc.webview = WKWebView()
vc.webview.navigationDelegate = vc

// When
let url = URL.init(string: "https://example.com/restOfUrl")
XCTAssertTrue(url!.absoluteString.contains("https://example.com"), "initial url string is wrong")
vc.webview.load(URLRequest(url: url!));
waitSeconds(duration: 2)

// Then
XCTAssertFalse(vc.openExternalBrowserCalled, "openExternalBrowserCalled value is wrong")
XCTAssertTrue(vc.openInternalBrowserCalled, "openInternalBrowserCalled value is wrong")
}

这给了我错误:

error: -[Tests.ViewControllerTests testOpenExternalBrowser_for_valid_urls] : failed: caught "NSInternalInconsistencyException", "Completion handler passed to -[ViewController webView:decidePolicyForNavigationAction:decisionHandler:] was not called"

这是相关的 WKWebKit ViewController 代码:

    // MARK: WKNavigationDelegate methods
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
guard let url = navigationAction.request.url, let urlScheme = url.scheme, let urlHost = url.host else {
//if we can't convert the URL, deny the action
decisionHandler(WKNavigationActionPolicy.cancel);
return;
}

var isPortValid = false;
if let urlPort = url.port {
isPortValid = urlPort == HostDefinitions.PORT;
} else {
isPortValid = urlScheme == DashboardConstants.HTTPS;
}

if(isPortValid && urlScheme == HostDefinitions.SCHEME && urlHost.compare(HostDefinitions.HOST) == ComparisonResult.orderedSame) {
openInternalBrowser(url: url, decisionHandler: decisionHandler)
return;
}

decisionHandler(WKNavigationActionPolicy.cancel);
openExternalBrowser(url: url)
}

func openInternalBrowser(url: URL, decisionHandler:@escaping (WKNavigationActionPolicy) -> Void) {
if(url.path == PathDefinitions.Login) {
//the user has logged out or visited the login page. We will now de-auth them and direct them back to the login page
OperationQueue.main.addOperation {
AuthManager.logout()
_ = self.navigationController?.popToRootViewController(animated: true);
}
decisionHandler(WKNavigationActionPolicy.cancel);
} else {
decisionHandler(WKNavigationActionPolicy.allow);
}
}

func openExternalBrowser(url: URL) {
AppManager.openExternalBrowser(url: url)
}

有什么想法吗?我试过添加一个返回语句并将决策处理程序添加到函数 openExternalBrowser 但都不起作用。应用程序正常运行(在 Safari 中打开外部 URL)但测试失败。

谢谢!

编辑:这是 MockDashboardViewController 代码:

class MockDashboardViewController: DashboardViewController {

var openInternalBrowserCalled = false
var openExternalBrowserCalled = false

var presentNotificationCalled = false

var webviewURLString = ""

override func openInternalBrowser(url: URL, decisionHandler:@escaping (WKNavigationActionPolicy) -> Void) {
openInternalBrowserCalled = true
}

override func openExternalBrowser(url: URL) {
openExternalBrowserCalled = true
}

override func presentNotification(notification: DashboardNotification, showAlertView: Bool) {
presentNotificationCalled = true
}
}

最佳答案

错误信息是正确的。你是说:

let vc = MockDashboardViewController()
vc.webview.navigationDelegate = vc

因此,Web View 的导航不是您的“相关 WKWebKit ViewController”,我认为它是 DashboardViewController,而是 DashboardViewController 的子类,即 MockDashboardViewController。它说:

override func openInternalBrowser(url: URL, decisionHandler:@escaping (WKNavigationActionPolicy) -> Void) {
openInternalBrowserCalled = true
}

好的,那么调用 decidePolicyFor 时会发生什么?在 MockDashboardViewController 中没有实现,所以调用 DashboardViewController 的实现:

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if(isPortValid && urlScheme == HostDefinitions.SCHEME && urlHost.compare(HostDefinitions.HOST) == ComparisonResult.orderedSame) {
openInternalBrowser(url: url, decisionHandler: decisionHandler)
return;
}
}

这就是执行路径上发生的所有事情。现在,decisionHandler 在哪里被调用?无处。运行时完全正确。

的确,decisionHandler 会在 DashboardViewController 的 openInternalBrowser(url:decisionHandler:) 实现中被调用。这就是为什么当您运行应用程序(而不是测试)时应用程序运行良好的原因。但是在您的测试子类中,您覆盖了它 — 而且您没有调用 super,因此您放弃了对 decisionHandler 的那些调用。

关于swift - NSInternalInconsistencyException 完成处理程序传递给 webView :decidePolicyForNavigationAction:decisionHandle was not called,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51508176/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com