2017-02-10 24 views
2

Мы сталкиваемся с прерывистым (иногда случаем на некоторых устройствах) сбоем, что нам трудно сжимать и неспособны воспроизводить по требованию. Это связано с Swift 3 и компонентом WKWebView, в частности, сбой протокола обратного вызова при попытке получить код ошибки с помощью оператора switch. смотри ниже:Swift WKWebView crash on 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: Error) ->()

...

Просмотр кода, кажется, как будто это должно быть эффективно свободным от проблем, так как переменная ERR должна быть успешно необязательно развернутой как действительный объект URLError к моменту выключения оператора switch. Оператору switch в этой точке должно быть гарантировано значение в err.code, поскольку .code не является обязательным для URLError.

Попытки искусственно вызвать ошибку, которая может объяснить проблему, до сих пор не обеспечили много понимания. то есть. если я создаю собственную собственную ошибку без свойства кода, а затем попытаюсь использовать ее как URLError, она изящно выпадает из необязательного назначения.

Любая помощь или предложения по возобновлению или даже дальнейшему устранению неполадок приветствуется, и в то же время будет продолжаться попытка воспроизводить на постоянной основе.

+0

Хорошо написанный вопрос. Получаете ли вы доступ к URL-адресам на своих серверах? Если да, то журналы сервера дают какое-либо представление об ошибке, которая может вызвать сбои в вашем приложении? –

+0

Это было отличное предложение, но колледж мой смог воспроизвести, прежде чем я смог добраться до него. Воспроизведение - просто ориентироваться с URL-адресом «http» с безопасностью транспорта приложений по умолчанию (разрешить произвольные нагрузки = нет). Хотя это позволяет нам обойти проблему, я буду отправлять ошибку, основанную на приведении в URLError, которая не содержит свойство .code. – 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

Итак, если вы столкнулись с сбоем при ссылке на свойство .code URLError, вы можете проверить его, выполнив приведение в NSError и проверку на свойство NSError .code.

Мы смягчающие его временного решение, пока ошибка не будет устранена (ниже рассматриваются только NSURLErrorAppTransportSecurityRequiresSecureConnection (интермедиат -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

Должно ли это быть 'if nserr.code == -1022 {' вместо 'if let nserr.code == -1022 {'? –

+0

Да, пожалуйста, извините опечатку. Решив сейчас. – Glorifundel