简体   繁体   English

Swift WKWebView 在 didFailProvisionalNavigation 上崩溃

[英]Swift WKWebView crash on didFailProvisionalNavigation

We are encountering an intermittent (happens on some devices, some of the time) crash that we are having a hard time nailing down, and are unable to reproduce on-demand.我们遇到了间歇性(在某些设备上,有时会发生)崩溃,我们很难确定,并且无法按需重现。 This is related to Swift 3 and the WKWebView component, specifically its callback protocol crashes when attempting to get the error code via a switch statement.这与 Swift 3 和 WKWebView 组件有关,特别是它的回调协​​议在尝试通过 switch 语句获取错误代码时崩溃。 see below:见下文:

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

  if let err = error as? URLError {

    switch(err.code) {  //  Exception occurs on this line
    case .cancelled:
      Hint(hide: true)

    case .cannotFindHost:
      Hint(hide: false, hint:.CannotFindHost)

    case .notConnectedToInternet:
      Hint(hide: false, hint: .NoInternet)

    case .resourceUnavailable:
      Hint(hide: false)

    case .timedOut:
      Hint(hide: false)

    default:
      Hint(hide: false)
      print("error code: " + String(describing: err.code) + "  does not fall under known failures")
    }
  }
}

func Hint(hide: Bool, hint:SomeCustomEnum = SomeCustomEnum.Default) {
     //Dosomething with ui to let user know something bad happened
}

the error stack indicates:错误堆栈指示:

0 _BridgedStoredNSError.code.getter 0 _BridgedStoredNSError.code.getter

1 _BridgedStoredNSError.code.getter 1 _BridgedStoredNSError.code.getter

2 specialized WebKitController.webView(WKWebView, didFailProvisionalNavigation : WKNavigation!, withError : Error) -> () 2 专门的 WebKitController.webView(WKWebView, didFailProvisionalNavigation : WKNavigation!, withError : Error) -> ()

3 @obj WebKitController.webView(WKWebView, didFailProvisionalNavigation : WKNavigation!, withError : Error) -> () 3 @obj WebKitController.webView(WKWebView, didFailProvisionalNavigation : WKNavigation!, withError : Error) -> ()

... ...

Reviewing the code it seems as if it should be effectively free from issues since the variable err should be successfully optionally-unwrapped as a valid URLError object by the time the switch statement is invoked.查看代码似乎它应该有效地没有问题,因为在调用 switch 语句时,变量 err 应该成功地选择性地解包为有效的 URLError 对象。 The switch statement at that point should be guaranteed a value in err.code since .code is not optional for URLError.应该保证此时的 switch 语句在 err.code 中有一个值,因为 .code 对于 URLError 不是可选的。

Attempts to artificially cause an error that might explain the issue have so far not provided much insight.迄今为止,试图人为地导致可能解释该问题的错误并没有提供太多洞察力。 ie. IE。 if I create my own custom error without a code property, then attempt to cast that as a URLError, it gracefully falls out of the optional assignment.如果我在没有代码属性的情况下创建自己的自定义错误,然后尝试将其转换为 URLError,它会优雅地脱离可选分配。

Any help or suggestions to revolve or even further troubleshoot is appreciated, in the mean time will continue to try to reproduce on a consistent basis.感谢任何帮助或建议来解决甚至进一步的故障排除,同时将继续尝试在一致的基础上重现。

When looking into the Swift Bug ( https://bugs.swift.org ) submission site I was able to find a description of the problem, ie.在查看 Swift Bug ( https://bugs.swift.org ) 提交站点时,我能够找到问题的描述,即。 Error cast to URLError can result in the property .code being missing:错误转换为 URLError 可能导致属性 .code 丢失:

https://bugs.swift.org/browse/SR-3879?jql=text%20~%20%22URLError%22 https://bugs.swift.org/browse/SR-3879?jql=text%20~%20%22URLError%22

This has a link to the following reference which seems to be the solution (still in process)这有一个指向以下参考的链接,这似乎是解决方案(仍在进行中)

https://bugs.swift.org/browse/SR-3881 https://bugs.swift.org/browse/SR-3881

Effectively URLError is missing two .code definitions:实际上 URLError 缺少两个 .code 定义:

NSURLErrorAppTransportSecurityRequiresSecureConnection NSURLErrorDataLengthExceedsMaximum NSURLErrorAppTransportSecurityRequiresSecureConnection NSURLErrorDataLengthExceedsMaximum

So if your encountering a crash when referencing the .code property of a URLError, you can check for it by casting to NSError and checking against the NSError .code property.因此,如果您在引用 URLError 的 .code 属性时遇到崩溃,您可以通过转换为 NSError 并检查 NSError .code 属性来检查它。

We are mitigating it with a temporary workaround until the bug is resolved (below only addresses the NSURLErrorAppTransportSecurityRequiresSecureConnection (int -1022) type failures):我们正在通过临时解决方法来缓解它,直到错误得到解决(下面仅解决 NSURLErrorAppTransportSecurityRequiresSecureConnection (int -1022) 类型故障):

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

  let nserr = error as NSError
  if nserr.code == -1022 {
    Hint(hide: false, hint: .NSURLErrorAppTransportSecurityRequiresSecureConnection)

  } else if let err = error as? URLError {

    switch(err.code) {  //  Exception no longer occurs
    case .cancelled:
      Hint(hide: true)

    case .cannotFindHost:
      Hint(hide: false, hint:.CannotFindHost)

    case .notConnectedToInternet:
      Hint(hide: false, hint: .NoInternet)

    case .resourceUnavailable:
      Hint(hide: false)

    case .timedOut:
      Hint(hide: false)

    default:
      Hint(hide: false)
      print("error code: " + String(describing: err.code) + "  does not fall under known failures")
    }
  }
}

func Hint(hide: Bool, hint:SomeCustomEnum = SomeCustomEnum.Default) {
     //Dosomething with ui to let user know something bad happened
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM