[WebKit] WKUserContentController : Web 과 상호작용

Sean·2023년 5월 26일
0

WebKit

목록 보기
4/4

누군가에게 알려주기 보다는 나 스스로 정리 하며 언젠가 다시 사용할 때를 대비하는 글을 작성할것이다.

참고자료 : WKUserContentController 공식문서

시작

Document: WKUserContentController

개요

  • JS 코드와 Web View 간 상호작용을 관리하고 Web View에서 컨텐츠를 필터링 하는데 사용되는 오브젝트

버전

  • iOS 8.0+
  • macOS 10.10+

번역

Overview

WKUserContentController 오브젝트는 앱과 웹 뷰에서 실행 중인 JavaScript 코드 사이의 연결을 제공한다.
다음의 오브젝트를 사용해 다음의 작업을 수행할 수 있다.

  • 웹 뷰에서 실행 중인 웹 페이지에 JavaScript 코드를 주입
  • 앱의 네이티브 코드로 연결되는 사용자 정의 JavaScript 함수를 설치
  • 제한된 콘텐츠가 로드되지 않도록 사용자 정의 필터를 지정

전체적으로 웹 뷰 설정으로 WKUserContentController 오브젝트를 생성하고 구성한다.
웹 뷰 생성 전 해당 오브젝트를 WKWebViewConfiguration 오브젝트의 userContentController 프로퍼티에 할당한다.

분석

Topic

커스텀 스크립트 추가 및 제거

  1. func addUserScript(WKUserScript)
    • 지정된 스크립트를 웹 페이지의 콘텐츠에 추가
  2. func removeAllUserScripts()
    • 웹 뷰에서 모든 사용자 스크립트를 제거
  3. var userScripts: [WKUserScript]
    • user content controller 와 연결된 사용자 스크립트

Message Handler 추가 및 제거

  1. func add(WKScriptMessageHandler, name: String)
    • JS 코드에서 호출 할 수 있는 핸들러 설치
  2. func add(WKScriptMessageHandler, contentWorld: WKContentWorld, name: String)
    • JS 의 컨텐츠 환경에서 호출 할 수 있는 핸들러 설치
  3. func addScriptMessageHandler(WKScriptMessageHandlerWithReply, contentWorld: WKContentWorld, name: String)
    • JS 의 회신을 반환하는 핸들러 설치
  4. func removeScriptMessageHandler(forName: String)
    • JS 코드에서 지정된 이름을 가진 핸들러 제거
  5. func removeScriptMessageHandler(forName: String, contentWorld: WKContentWorld)
    • JS 코드의 컨텐츠 환경에서의 핸들러 제거
  6. func removeAllScriptMessageHandlers(from: WKContentWorld)
    • JS 코드의 컨텐츠 환경에서 모든 핸들러 제거
  7. func removeAllScriptMessageHandlers()
    • user content controller 와 연결된 모든 핸들러 제거
  8. protocol WKScriptMessageHandler
    • 웹 페이지에서 실행되는 JS 코드의 매시지 수신 위한 인터페이스
  9. protocol WKScriptMessageHandlerWithReply
    • 웹 페이지에서 실행되는 JS 코드의 메시지 응답 위한 인터페이스

컨텐츠 규칙 추가 및 제거

  1. func add(WKContentRuleList)
    • 컨텐츠 컨트롤러 오브젝트에 지정된 규칙 목록을 추가
  2. func remove(WKContentRuleList)
    • 컨텐츠 컨트롤러 오브젝트에서 지정된 규칙 목록 제거
  3. func removeAllContentRuleLists()
    • 컨텐츠 컨트롤러에서 모든 규칙 제거
  4. class WKContentRuleList
    • 웹 컨텐츠에 적용할 컴파일된 규칙의 리스트

사용

해당 기능을 사용하기 위해서는 웹 뷰는 코드로 생성을 해야 한다.
웹 뷰 초기화 함수의 configuration을 사용해야 하는데 이는 코드로만 접근이 가능하기 때문이다.

let contentController = WKUserContentController()
let cofiguration = WKWebViewConfiguration()

contentController.add(self, name: "MyInterfaceName")

configuration.userContentController = contentController

let webView = WKWebView(frame: .zero, configuration: configuration)

WKScriptMessageHandler 를 채택해 해당 프로토콜의 func userContentController(WKUserContentController, didReceive: WKScriptMessage) 함수로 이벤트를 받아온다.

WKScriptMessage 은 다음과 같은 형태를 띄고 있다.

open class WKScriptMessage : NSObject {
    open var body: Any { get }
    weak open var webView: WKWebView? { get }
    @NSCopying open var frameInfo: WKFrameInfo { get }
    open var name: String { get }
    @available(iOS 14.0, *)
    open var world: WKContentWorld { get }
}

프로토콜을 채택해서 함수로 이벤트를 받아오는 방법은 다음과 같다.

class WebViewController: WKScriptMessageHandler {
	func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
	    let name = message.name
    	if let body = message.body as? String {
        	...
        }
    }
}

이런식으로 message 를 사용하여 받아온 값을 다루면 된다.

이거 테스트 하는 방법은 웹을 직접 할 수 있는 분이 개발자용 도구 열어서 하라고는 하는데
필자는 진행하는 프로젝트에서 사용하는 부분인지라 다 구현이 되어있어서 따로 직접 웹 관련 무언가는 하지 않아서 해당 부분에 대해서는 따로 말을 해줄 수는 없다.

참고자료

기타

당연 틀린 부분 지적은 감사하나 비난은 정중하게 사양하겠다.

profile
"잘 할 수 있을까?"를 고민하기보단 재밌어 보이는건 일단 하고, 잘하기 위해 그냥 계속합니다.

0개의 댓글