[iOS] WKWebView 새 창 및 alert, confirm 처리

pola·2025년 2월 26일

Company

목록 보기
5/7
  • WKWebView를 사용할 때, 기본적으로 새 창(window.open) 및 alert(), confirm() 함수가 동작하지 않음
  • 보안 정책 중 하나로 Safari에서 click event만 지원함
  • 이를 해결하기 위해 WKUIDelegate를 활용하여 적절한 처리를 해주어야함

1. 새 창 열기 (window.open 대응)

문제

  • WKWebView에서 window.open이 호출될 때 새로운 창이 열리지 않음

해결 방법

  • createWebViewWith 메서드를 구현하여 새 창을 열어줄 수 있도록 처리

구현 코드

func webView(
    _ webView: WKWebView,
    createWebViewWith configuration: WKWebViewConfiguration,
    for navigationAction: WKNavigationAction,
    windowFeatures: WKWindowFeatures
) -> WKWebView? {
    let frame = UIScreen.main.bounds

    // 파라미터로 받은 configuration을 적용한 새로운 WKWebView 생성
    newWebView = WKWebView(frame: frame, configuration: configuration)

    newWebView!.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    newWebView!.navigationDelegate = self
    newWebView!.uiDelegate = self
    newWebView!.tag = 100

    webView.addSubview(newWebView!)

    return newWebView!
}

2. 새 창 닫기 (window.close 대응)

문제

  • 웹에서 window.close()를 호출해도 WKWebView에서 창이 닫히지 않음

해결 방법

  • webViewDidClose를 구현하여 새 창을 닫을 수 있도록 처리

구현 코드

func webViewDidClose(_ webView: WKWebView) {
    if webView == newWebView {
        newWebView.removeFromSuperview()
        newWebView = nil
    }
}

3. Alert 및 Confirm 창 처리 (alert(), confirm() 대응)

문제

  • WKWebView에서 JavaScript의 alert()confirm()이 동작하지 않음

해결 방법

  • WKUIDelegaterunJavaScriptAlertPanelWithMessagerunJavaScriptConfirmPanelWithMessage 메서드를 구현하여 iOS 네이티브 UIAlertController로 처리

Alert 처리 (alert())

func webView(
    _ webView: WKWebView,
    runJavaScriptAlertPanelWithMessage message: String,
    initiatedByFrame frame: WKFrameInfo,
    completionHandler: @escaping () -> Void
) {
    let alertController = UIAlertController(title: "알림", message: message, preferredStyle: .alert)
    let cancelAction = UIAlertAction(title: "확인", style: .cancel) { _ in
        completionHandler()
    }
    alertController.addAction(cancelAction)
    DispatchQueue.main.async {
        self.present(alertController, animated: true, completion: nil)
    }
}

Confirm 처리 (confirm())

func webView(
    _ webView: WKWebView,
    runJavaScriptConfirmPanelWithMessage message: String,
    initiatedByFrame frame: WKFrameInfo,
    completionHandler: @escaping (Bool) -> Void
) {
    let alertController = UIAlertController(title: "알림", message: message, preferredStyle: .alert)
    let cancelAction = UIAlertAction(title: "취소", style: .cancel) { _ in
        completionHandler(false)
    }
    let okAction = UIAlertAction(title: "확인", style: .default) { _ in
        completionHandler(true)
    }
    alertController.addAction(cancelAction)
    alertController.addAction(okAction)
    DispatchQueue.main.async {
        self.present(alertController, animated: true, completion: nil)
    }
}

4. 결론

  • window.open을 통해 새 창을 띄울 경우 createWebViewWith에서 새로운 WKWebView를 생성하여 처리
  • window.close를 통해 창을 닫을 경우 webViewDidClose를 활용하여 닫아줌
  • JavaScript의 alert()confirm()이 동작하지 않는 문제는 runJavaScriptAlertPanelWithMessagerunJavaScriptConfirmPanelWithMessage를 통해 해결

이렇게 처리하면 WKWebView에서도 웹의 기본적인 창 생성 및 경고창 기능을 원활하게 사용할 수 있음

profile
pola

0개의 댓글