WKWebView 양방향 통신 - ehrldyd15/Swift_Skills GitHub Wiki

WKWebView 양방향 통신

Swift -> JavaScript

  • WKUserScript 사용

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

스크린샷 2022-08-08 오후 2 50 01

  • 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

스크린샷 2022-08-08 오후 3 07 47

  • 구현 방법

    • WKScriptMessageHandler 프로토콜 준수

    • 사전에 JavaScript와 클라이언트 간에 정의한 interface이름을 WKUserContentController() 인스턴스에 등록

    • JavaScript에서 webkit.messageHandlers로 액션 호출하면 swift의 WKScriptMessageHandler델리게이트 호출

스크린샷 2022-08-08 오후 3 10 03

  • 구현

      // 문자열 파싱하여 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://ios-development.tistory.com/752