bannaviiOS) wkWebView 뽀개기(feat. WKUserContentController)

2022. 11. 25. 10:47iOS/iOS

728x90
반응형

 

역할이 무엇이니

 

 

웹뷰 구동원리에 대해 깊이 이해를 하고싶었습니다.

그래서 개발문서, 블로그 등을 활용하여 WKUserContentController에 대해 정리해보았습니다.

 

 

 

WKUserContentController

JavaScript 코드와 웹뷰 간의 상호 작용을 관리하고 웹뷰의 내용을 필터링하기 위한 객체.

 

 

WKUserContentController 객체는 앱과 웹뷰에서 실행되는 JavaScript 코드 사이에 브릿지를 제공합니다.

WKUserContentController 객체는 다음의 수행을 도와줍니다.

1. 웹뷰에서 실행 중인 웹 페이지에 JavaScript 코드를 삽입합니다.

2. 앱의 네이티브 코드를 호출하는 사용자 지정 JavaScript 함수를 설치합니다.

3. 웹 페이지가 제한된 콘텐츠를 로드하지 않도록 사용자 지정 필터를 지정합니다.

4. 전체 웹뷰 설정의 일부로 WKUserContentController 객체를 만들고 구성합니다.

웹뷰를 만들기 전에 WKWebViewConfiguration 객체의 userContentController 속성에 객체를 할당합니다.

 

 

주의)

1. WKUserContentController 기능을 사용하려면 웹뷰는 코드로 생성해야 합니다.

-> 웹뷰 초기화 함수의 configuration속성을 사용해야 하는데 스토리보드로는 해당 속성을 사용 못하기 때문입니다.

 

func initWebview() {
        let preferences = WKPreferences()
        let webConfiguration = WKWebViewConfiguration()
        let contentController = WKUserContentController()
        preferences.javaScriptCanOpenWindowsAutomatically = true
        preferences.javaScriptEnabled = true //javascript활성화
        webConfiguration.selectionGranularity = .dynamic
        
        //웹뷰를 만들기 전에 WKWebViewConfiguration 객체의 userContentController 속성에 객체를 할당합니다.
        webConfiguration.userContentController = contentController
        webConfiguration.preferences = preferences
        
        //add함수를 통해 브릿지 이름 설정.(서버쪽과 상의된 브릿지 이름을 넣는다)
        //웹뷰와 인터페이스 연결
        contentController.add(self, name: TSConst.TS_MAIN_SCHEME)
        
        //configuration을 적용하기위해 webView를 코드로 그리고 있는 모습.
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.uiDelegate = self
        webView.navigationDelegate = self
        webView.scrollView.alwaysBounceVertical = false
        webView.scrollView.isScrollEnabled = false
        webView.scrollView.bounces = false
        webView.scrollView.scrollsToTop = true
        self.view.addSubview(webView)
        webView.snp.makeConstraints {
            $0.edges.equalTo(self.view.safeAreaLayoutGuide)
        }
}

 

WKUserContentController

 

웹뷰와 연결된 UserContentController는 웹뷰 구성에 의해 아래와 같이 지정됩니다.

 

 

1.

@available(iOS 14.0, *)

    open func add(_ scriptMessageHandler: WKScriptMessageHandler, contentWorld world: WKContentWorld, name: String)

- 스크립트 메시지 핸들러를 추가합니다.

- scriptMessageHandler 추가할 스크립트 메시지 핸들러.

- contentWorld 스크립트 메시지 핸들러를 추가할 WKContentWorld.

- name 메시지 핸들러의 이름입니다. name 인수는 비어 있지 않은 문자열이어야 합니다. 각 WK Content World에는 원하는 수의 스크립트 메시지 핸들러가 있을 수 있지만 고유한 이름당 하나만 있습니다. 이전 스크립트 메시지 핸들러를 먼저 제거하지 않고 스크립트 메시지 핸들러를 같은 이름의 WKContentWorld로 보내는 것은 오류입니다. 이는 모든 유형의 스크립트 메시지 핸들러(WKscriptMessageHandler 및 WKScriptMessageHandlerWithReply)에 적용됩니다. -> 개체를 동일한 이름으로 동일한 WK Content World에 추가하려고 하면 개체가 서로 충돌합니다.

- 아래의 스크립트 메시지 핸들러를 추가하면 모든 frame에 기능이 추가되고, 지정된 WKContentWorld에서 사용할 수 있습니다.

window.webkit.messageHandlers.<name>.postMessage(<messageBody>)

 

 

2.

@available(iOS 14.0, *)   open func addScriptMessageHandler(_ scriptMessageHandlerWithReply: WKScriptMessageHandlerWithReply, contentWorld: WKContentWorld, name: String)

- 위의 주황색 내용과 같음

- 흠.. 첫번째 파라미터만 다르넹..

- WKScriptMessageHandler보다 유연한 방법에 대한 예는 WKScriptMessageHandlerWithReply 설명서를 참조하십시오.

 

 

3.

open func add(_ scriptMessageHandler: WKScriptMessageHandler, name: String)

- 이 메서드를 호출하는 것은 addScriptMessageHandler:contentWorld:name:을 호출하는 것과 같습니다.
- [WKContentWorld pageWorld]를 contentWorld 인수로 사용합니다.

- 페이지 내용 자체에서 사용하는 main world에 스크립트 메시지 핸들러를 추가합니다.
@param scriptMessageHandler 추가할 스크립트 메시지 핸들러.
@param name 메시지 처리기의 이름입니다.

 

 

4.

open var userScripts: [WKUserScript] { get }

- 이 usercontentcontroller 와 관련된 userScripts

 

 

 

5.

open func addUserScript(_ userScript: WKUserScript)

- user script를 추가합니다.

 

 

 

6.

open func removeAllUserScripts()

- 연관된 모든 사용자 script를 제거합니다.

 

 

 

7.

    @available(iOS 14.0, *)

    open func removeScriptMessageHandler(forName name: String, contentWorld: WKContentWorld)

- 스크립트 메시지 핸들러를 제거합니다.

- @param name 제거할 메시지 핸들러

- @param contentWorld 스크립트 메시지 처리기를 제거할 WKContentWorld

 

    

 

8.

    open func removeScriptMessageHandler(forName name: String)

- 스크립트 메시지 핸들러를 제거합니다.

- @param name 제거할 메시지 핸들러

- 이 메서드를 호출하는것은 removeScriptMessageHandlerForName:contentWorld:를 호출하는 것과 같습니다.

    

 

 

 

9.

    @available(iOS 14.0, *)

    open func removeAllScriptMessageHandlers(from contentWorld: WKContentWorld)

- 지정된 WK Content World에서 모든 스크립트 메시지 핸들러를 제거합니다.

- @param contentWorld 모든 스크립트 메시지 처리기를 제거하는 WKContentWorld.

 

    

 

10.

    @available(iOS 14.0, *)

    open func removeAllScriptMessageHandlers()

- 연결된 모든 스크립트 메시지 핸들러를 제거합니다.

    

 

 

 

11.

    @available(iOS 11.0, *)

    open func add(_ contentRuleList: WKContentRuleList)

- 콘텐트 규칙 목록을 추가합니다.

    

 

 

 

12.

    @available(iOS 11.0, *)

    open func remove(_ contentRuleList: WKContentRuleList)

- 콘텐트 규칙 목록을 제거합니다.

    

 

 

13.

    @available(iOS 11.0, *)

    open func removeAllContentRuleLists()

- 연결된 모든 콘텐트 규칙 목록을 제거합니다.

 

 

 

 

 

 

 

 

참고자료

- https://developer.apple.com/documentation/webkit/wkusercontentcontroller

- https://zetal.tistory.com/entry/WKUserContentController

728x90
반응형