관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 3. WKWebView - 양방향 통신, WKUserScript, WKScriptMessageHandler 델리게이트를 구현하여 JavaScript interface 사용 방법 본문

iOS 응용 (swift)

[iOS - swift] 3. WKWebView - 양방향 통신, WKUserScript, WKScriptMessageHandler 델리게이트를 구현하여 JavaScript interface 사용 방법

jake-kim 2021. 11. 9. 00:35

1. WKWebView - UIToolBar 사용하여 뒤로가기, 앞으로가기  구현 (goBack(), goForward())

2. WKWebView - Header 설정, Cookie 설정, access token 전달, deeplink 수신 방법

3. WKWebView - 양방향 통신, WKUserScript, WKScriptMessageHandler 델리게이트를 구현하여 JavaScript interface 사용 방법

Swift -> JavaScript

  • WKUserScript 사용
    • webView에서 웹페이지로 script를 주입시킬때 사용하는 script

  • WKUserContentController() 인스턴스에 WKUserScript 값을 추가하고, WKUserContentController인스턴스를 WKWebViewConfiguration에 설정하여 WKWebView 생성
    • atDocumentEnd: 문서 로드가 완료된 후 다른 하위 리소스를 로드하기 전에 스크립트를 삽입
let configuration = WKWebViewConfiguration()

// Swift가 Javascript에게 testJavascriptMethod() 호출 요청
let userScript = WKUserScript(source: "testJavascriptMethod()", injectionTime: .atDocumentEnd, forMainFrameOnly: true)
let contentController = WKUserContentController()
contentController.addUserScript(userScript)
configuration.userContentController = contentController

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

Swift <- JavaScript 이벤트 수신 방법

  • WKScriptMessageHandler 델리게이트 구현
    • 웹페이지에서 동작하는 JavaScript 코드로 부터 받는 interface

  • 구현 방법
    • 1) WKScriptMessageHandler 프로토콜 준수
    • 2) 사전에 JavaScript와 클라이언트 간에 정의한 interface이름을 WKUserContentController() 인스턴스에 등록
    • 3) JavaScript에서 webkit.messageHandlers로 액션 호출하면 swift의 WKScriptMessageHandler델리게이트 호출

ex) JavaScript 인터페이스 

시그니처 javascript
statusBar 색상 변경: changeStatusBarColor webkit.messageHandlers.MyJavaScriptInterfaces.postMessage([
    action: 'changeStatusBarColor',
    bgColor: '#FFFFFF'
    isDarkIcon: true
])
뒤로가기 버튼 누른 경우: goBack webkit.messageHandlers.MyJavaScriptInterfaces.postMessages([
    action: 'goBack',
])
  • 구현
// 문자열 파싱하여 WebAction을 구분하는데 사용되는 타입 정의
enum WebAction: String {
    case changeStatusBarColor
    case goBack
}

// Swift에 JavaScript 인터페이스 연결
contentController.add(self, name: "MyJavaScriptInterfaces") // delegate 채택

// WKScriptMessageHandler 구현
extension WebViewController: WKScriptMessageHandler {
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        guard message.name == "MyJavaScriptInterfaces",
              let messages = message.body as? [String: Any],
              let action = messages["action"] as? String else { return }

        let webAction = WebAction(rawValue: action)
        switch webAction {
        case .changeStatusBarColor:
            if let color = messages["bgColor"] as? String {
                print("change status bar color = \(color)")
            }
        case .goBack:
            print("goBack")
        default:
            print("undefined action")
        }
    }
}

* 전체 코드: https://github.com/JK0369/ExWKWebView/tree/ImplementJavaScriptInterface

 

 

* 참고

- WKScriptMessageHandler: https://developer.apple.com/documentation/webkit/wkscriptmessagehandler

- WKUserScript: https://developer.apple.com/documentation/webkit/wkuserscript

- WKScriptMessageHandler: https://developer.apple.com/documentation/webkit/wkscriptmessagehandler

Comments