생계유지형 개발자/Stack Over Flow 한국판
[ios] Completion handler passed to -[Connect.MainViewController webView:decidePolicyForNavigationAction:decisionHandler:] was called more than once
이 가을
2020. 7. 30. 17:56
# 오류
WebView 함수에서 화면 왔다갔다 하는 중에 다음과 같은 오류가 발생하면서 앱이 멈춘다.
Exception: "Completion handler passed to -[Connect.MainViewController webView:decidePolicyForNavigationAction:decisionHandler:] was called more than once"
위의 에러가 발생한 소스코드 위치는 아래에서 에러발생지점 이라고 표시한 라인이다.
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
let destinationUrl = (navigationAction.request.url?.absoluteString)! as NSString // 목적지 url
if destinationUrl.contains(Helper.logInUrl) {
decisionHandler(.cancel)
}
if destinationUrl.hasPrefix(Helper.appSchema) {
decisionHandler(.cancel)
}
decisionHandler(.allow) // <-- 에러발생지점
}
# 원인
정확한 원인은 잘 모르겠지만, 정책상(?) decisionHandler()는 한번만 호출될 수 있다.
함수가 한번 실행되는 동안 .cancel 로 했다가 .allow 로 바꿀 수 없다는 것이다.
그래서 decisionHandler()를 했으면 바로 return 시켜주는 것이 오류를 방지하는 안전한 방법이다.
# 해결
함수끝낼 때 decisionHandler 앞에 return을 붙여주거나 마지막에 Void로 return 해 주니 해결되었다.
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
let destinationUrl = (navigationAction.request.url?.absoluteString)! as NSString // 목적지 url
if destinationUrl.contains(Helper.logInUrl) {
decisionHandler(.cancel)
return
}
if destinationUrl.hasPrefix(Helper.appSchema) {
decisionHandler(.cancel)
return
}
decisionHandler(.allow)
// return 맨 마지막 생략 가능
}
※ 참고
https://github.com/marcuswestin/webviewjavascriptbridge/issues/278