오류
다른 ViewController에서 동시에 한 개의 webView를 사용하고 있던 중 아래 오류가 발생하였다.
Completion handler passed to [webView:decidePolicyForNavigationAction:decisionHandler:] was called more than once
원인
webView에서 decideHandler나 completionHandler의 호출은 한 번 밖에 되지 않는다.
해결
CompletionHandlerWrapper Class를 선언하여 webView에 적용
class CompletionHandlerWrapper<Element> {
private var completionHandler: ((Element) -> Void)?
private let defaultValue: Element
init(completionHandler: @escaping ((Element) -> Void), defaultValue: Element) {
self.completionHandler = completionHandler
self.defaultValue = defaultValue
}
func respondHandler(_ value: Element) {
completionHandler?(value)
completionHandler = nil
}
deinit {
respondHandler(defaultValue)
}
}
func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
let completionHandlerWrapper = CompletionHandlerWrapper(completionHandler: completionHandler, defaultValue: false)
let alertController = UIAlertController(title: message, message: nil, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "확인", style: .default) { _ in completionHandlerWrapper.respondHandler(true) })
alertController.addAction(UIAlertAction(title: "취소", style: .cancel) { _ in completionHandlerWrapper.respondHandler(false) })
present(alertController, animated: true, completion: nil)
}
출처