2017-02-10 284 views
2

我们遇到了间歇性(发生在某些设备上,某些时候)的崩溃,我们很难确定是否需要重新定位并且无法按需重现。这与Swift 3和WKWebView组件有关,特别是当它试图通过switch语句获取错误代码时,它的回调协​​议崩溃。见下文:swift WKWebView在didFailProvisionalNavigation上崩溃

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 
} 

错误堆栈指示:

0 _BridgedStoredNSError.code.getter

1 _BridgedStoredNSError.code.getter

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

3 @obj WebKitController.webView(WKWebView,didFailProvisionalNavigat离子:WKNavigation!withError:错误) - >()

...

回顾它好像应该从问题的有效自由自变量ERR应该是成功任选展开的代码有效的URLError对象在switch语句被调用时。此时的switch语句应该在err.code中保证一个值,因为.code对于URLError不是可选的。

尝试人为地导致可能解释问题的错误至今尚未提供多少见解。即。如果我在没有代码属性的情况下创建自己的自定义错误,则尝试将其作为URLError进行强制转换,它会优雅地脱离可选分配。

任何有关旋转甚至进一步故障排除的帮助或建议都会受到赞赏,同时还会继续尝试在一致的基础上重现。

+0

写得很好的问题。您是否正在访问您拥有的服务器上的网址?如果是这样,那么服务器日志是否提供了有关可能导致应用程序崩溃的错误的信息? –

+0

这是一个很好的建议,但我的一个大学能够在我能够实现之前重现。复制只需在默认情况下使用带有应用程序传输安全性的“http”网址进行导航(允许任意加载=否)模式。虽然这确实让我们解决了这个问题,但我会根据转换将错误提交给不包含.code属性的URLError。 – Glorifundel

回答

2

当查看Swift Bug(https://bugs.swift.org)提交网站时,我能够找到问题的描述,即。错误投地URLError可能导致财产.CODE是丢失:

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

这有一个链接后面的参考,这似乎是解决方案(仍在进行中)

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

有效地,URLError缺少两个.code定义:

NSURLErrorAppTransportSecurityRequiresSecureConnection NSURLErrorDataLengthExcee dsMaximum

因此,如果在引用URLError的.code属性时遇到崩溃,可以通过转换为NSError并检查NSError .code属性来检查它。

我们正在与一个暂时的解决办法减轻它,直到错误被解决(以下只解决了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 
} 
+0

应该是'如果nserr.code == -1022 {'而不是'如果让nserr.code == -1022 {'? –

+0

是的,请原谅打字错误。现在解决。 – Glorifundel