2017-02-10 176 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