ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Swift6] WebView 에서 워닝이 발생할 때
    iOS 2025. 4. 25. 13:47
    반응형

    Swift6 를 대응하다보면 바로 하기엔 수정 규모가 너무 크기 때문에
    Strict Concurrency Checking 을 우선 minimal 로 두고 워닝을 제거하는 과정을 거치게 됩니다.

    이때 WebView를 Import 하는 부분에서 워닝이 발생합니다.

    Add '@preconcurrency' to suppress 'Sendable'-related warnings from module 'WebKit'

    코드엔 워닝이 없고 다짜고짜 import 에 워닝이라니...
    이때 제안해주는 대로 @preconcurrency 를 바로 붙이자니 찜찜합니다.

    다행히 Strict Concurrency Checking을 Complete로 변경하면 문제가 되는 코드를 찾을 수 있습니다.

     


     

    # WKNavigationDelegate

    WKNavigationDelegate 를 준수한 메서드에서 워닝이 발생하는 경우가 있다면,

    Instance method 'webView(_:decidePolicyFor:decisionHandler:)' nearly matches optional requirement 'webView(_:decidePolicyFor:decisionHandler:)' of protocol 'WKNavigationDelegate'

    그냥 무지성으로 제안해주는 Fix를 그냥 하면 메서드를 private으로 바꾼다던가, 제대로 동작하지 않습니다.

    하지만 진짜 이유는
    WKNavigationDelegate 의 메서드 시그니쳐가 Sendable을 준수하게 변경되었는데, 거기에 맞춰 변경되지 않았기 때문일 것입니다.

    가령 아래와 같이 사용하고 있었지만

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void)

     

    이런 식으로 변경되었습니다.

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping @MainActor @Sendable (WKNavigationActionPolicy) -> Void) {

     

     

    # deinit

    deinit 에서 webView 의 값을 변경해주는 코드들이 있다면,

    deinit {
        self.webView?.navigationDelegate = nil
        self.webView?.uiDelegate = nil
        self.webView?.stopLoading()
    }

     

     

    deinit 에서 self 캡쳐하면 self가 제대로 메모리에서 제거되지 않을 수 있기 때문에  문제가 됩니다.
    필요한 객체를 캡쳐해서 처리하는 게 좋습니다.

    deinit {
        Task { @MainActor [webView] in
            webView?.navigationDelegate = nil
            webView?.uiDelegate = nil
            webView?.stopLoading()
        }
    }

     

     

    감사합니다.

     

     

    반응형

    댓글

Designed by Tistory.