07 May 2024

iOS 앱과 웹페이지 간의 통신은 WKWebView을 이용하여 쉽게 구현할 수 있습니다. 웹페이지는 iOS 앱으로 데이터를 전달하면, iOS 앱은 웹페이지의 JavaScript 함수를 호출할 수 있습니다.

웹페이지 -> iOS

웹에서 iOS 앱으로 데이터를 전달하는 방법은 서로 약속한 이름을 가진 window.webkit.messageHandlers의 객체를 이용하는 방법이 있습니다.

window.webkit.messageHandlers.actionHandler.postMessage({
    "action": "hello",
    "message": "Hello from JavaScript!"
});
Html Source Code


앱과 웹페이지 간의 약속한 이름인 actionHandler 객체를 postMessage 함수를 이용하여 iOS 앱으로 데이터를 전달합니다.

iOS 앱은 WKUserContentControlleractionHandler 메시지 핸들러를 등록하고, WKScriptMessageHandler 프로토콜 메소드인 func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)를 구현합니다.

class ViewController: UIViewController, WKScriptMessageHandler {
  var webView: WKWebView?

  override func viewDidLoad() {
    super.viewDidLoad()

    // WKUserContentController 인스턴스 생성
    let userContentController = WKUserContentController()
    userContentController.add(self, name: "actionHandler") // 메시지 핸들러 등록
      
    // WKWebView에 WKUserContentController 설정
    let configuration = WKWebViewConfiguration()
    configuration.userContentController = userContentController
      
      
    // WKWebView 인스턴스 생성
    let webView = WKWebView(frame: view.bounds, configuration: configuration)
    self.webView = webView

    view.addSubview(webView)
  }

  // WKScriptMessageHandler 프로토콜 메서드 구현
  func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    print(message.name, message.body)

    guard
      message.name == "actionHandler",
      let messageBody = message.body as? [String: Any]
    else { return }  

    print("Received message from JavaScript: \(messageBody)") // 웹으로부터 받은 메시지를 파싱하여 print를 호출하는 코드.
  }
}

웹페이지에서 actionHandler 객체를 이용하여 전달한 데이터를 iOS 앱에서 수신하는 것을 아래 영상에서 확인할 수 있습니다.





iOS -> 웹페이지

WKWebView에서는 evaluateJavaScript 메서드를 이용하여 웹페이지의 JavaScript 함수를 호출할 수 있습니다.

위의 코드에서 action이 hello 인 경우, 웹페이지의 javaScriptFunction 함수를 호출하도록 코드를 수정해봅시다.

// WKScriptMessageHandler 프로토콜 메서드 구현
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
  guard
    message.name == "actionHandler",
    let messageBody = message.body as? [String: Any],
    let action = messageBody["action"] as? String
  else { return }
  
  print("Received message from JavaScript: \(messageBody)") // 웹으로부터 받은 메시지를 파싱하여 print를 호출하는 코드.
  
  if action == "hello" {
    let jsFunctionCall = "javaScriptFunction();"
    webView?.evaluateJavaScript(jsFunctionCall, completionHandler: nil) // WKWebView에서 JavaScript 코드 실행
  } else if action == "log" {
    print("Called javascript function")
  }
}

웹페이지에서 javaScriptFunction 함수를 호출되고 다시 action에 log로 앱으로 호출하는 코드를 아래 영상에서 확인할 수 있습니다.



정리

  • 앱과 웹은 약속한 이름을 가진 객체와 함수의 이름을 사용하여 통신합니다.

예제 코드

참고자료