본문 바로가기
iOS

[iOS] WebKit - WKScriptMessageHandler, WKScriptMessageHandlerWithReply

by Bokoo14 2025. 2. 22.

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

 

WKScriptMessageHandler | Apple Developer Documentation

An interface for receiving messages from JavaScript code running in a webpage.

developer.apple.com

 

페이지에서 실행되는 JavaScript 코드에서 메시지를 수신하기 위한 인터페이스

JavaScript → Swift 메시지 전달을 처리하는 프로토콜
웹뷰 내 JavaScript 코드에서 window.webkit.messageHandlers.이름.postMessage(데이터)를 호출하면 Swift에서 해당 메시지를 받아 처리할 수 있다.

 

필수 구현 메서드

https://developer.apple.com/documentation/webkit/wkscriptmessagehandler/usercontentcontroller(_:didreceive:)

 

userContentController(_:didReceive:) | Apple Developer Documentation

Tells the handler that a webpage sent a script message.

developer.apple.com

웹페이지에서 스크립트 메시지를 보냈음을 핸들러에게 알린다.

 방법을 사용하여 웹페이지의 JavaScript 코드에서 보낸 메시지에 응답한다. 

메시지 매개변수를 사용하여 메시지 내용을 가져오고 원래  뷰를 확인한다.

Parameters

  • userContentController
    • 메시지를 핸들러에 전달한 사용자 콘텐츠 컨트롤러
  • message
    • 메시지 세부 정보가 포함된 객체
func userContentController(
	_ userContentController: WKUserContentController, 
	didReceive message: WKScriptMessage
){ }

 

사용 예시 - iOS

import UIKit
import WebKit

class WebViewController: UIViewController, WKScriptMessageHandler {
    var webView: WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let contentController = WKUserContentController()
        contentController.add(self, name: "nativeHandler")  // JS에서 "nativeHandler" 이름으로 메시지 전송 가능
        
        let config = WKWebViewConfiguration()
        config.userContentController = contentController
        
        webView = WKWebView(frame: view.bounds, configuration: config)
        view.addSubview(webView)
        
        if let url = URL(string: "https://example.com") {
            webView.load(URLRequest(url: url))
        }
    }
    
    // 필수 구현 메서드, JavaScript에서 호출되는 메서드
    func userContentController(
	_ userContentController: WKUserContentController,
	didReceive message: WKScriptMessage
	) {
        if message.name == "nativeHandler", let body = message.body as? String {
            print("JavaScript에서 받은 메시지: \(body)")
        }
    }
}

사용 예시 - JS

window.webkit.messageHandlers.nativeHandler.postMessage("Hello, Swift!");

 


WKScriptMessageHandlerWithReply

 

JavaScript에서 메시지를 보내면 Swift가 응답을 반환할 수 있도록 하는 프로토콜

기존 WKScriptMessageHandler와 다르게 JavaScript에서 보낸 메시지에 대해 Swift가 값을 반환할 수 있다.

WKScriptMessageHandlerWithReply는 비동기 응답을 제공하는 메시지 핸들러로, JavaScript → Swift → JavaScript 순서로 통신할 수 있다. 

필수 구현 메서드

https://developer.apple.com/documentation/webkit/wkscriptmessagehandlerwithreply/usercontentcontroller(_:didreceive:replyhandler:)

 

userContentController(_:didReceive:replyHandler:) | Apple Developer Documentation

Tells the handler that a webpage sent a script message that included a reply.

developer.apple.com

JavaScript에서 메시지를 받으면 Swift에서 처리 후 응답을 반환

 

Parameters

  • userContentController
    • 메시지를 핸들러에 전달한 사용자 콘텐츠 컨트롤러
  • message
    • 메시지 세부 정보가 포함된 객체
  • replyHandler
    • 웹페이지로 다시 보낼 응답과 함께 실행할 응답 핸들러 블록. 이 블록에는 반환 값이 없으며 다음 매개변수를 사용
    • reply
    • errorMessage
      • nil성공 또는 발생한 오류를 설명하는 문자열

사용 예시 - iOS

import UIKit
import WebKit

class WebViewController: UIViewController, WKScriptMessageHandlerWithReply {
    var webView: WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let contentController = WKUserContentController()
        contentController.addScriptMessageHandler(self, contentWorld: .page, name: "nativeHandler")

        let config = WKWebViewConfiguration()
        config.userContentController = contentController
        
        webView = WKWebView(frame: view.bounds, configuration: config)
        view.addSubview(webView)
        
        if let url = URL(string: "https://example.com") {
            webView.load(URLRequest(url: url))
        }
    }
    
    // 필수 구현 메서드: JavaScript에서 메시지를 보내면 처리 후 응답을 반환
    func userContentController(
    	_ userContentController: WKUserContentController, 
        didReceive message: WKScriptMessage, 
        completionHandler: @escaping (Any?, String?) -> Void
	) {
        if message.name == "nativeHandler", let body = message.body as? String {
            print("JavaScript에서 받은 메시지: \(body)")
            
            // Swift에서 JavaScript로 응답 반환
            let response = "Swift에서 응답: \(body.uppercased())"
            completionHandler(response, nil)  // (응답 데이터, 오류 메시지)
        } else {
            completionHandler(nil, "잘못된 메시지 형식")  // 오류 반환 가능
        }
    }
}

사용 예시 - JS

async function sendMessageToNative() {
    try {
        let response = await window.webkit.messageHandlers.nativeHandler.postMessage("Hello, Swift!");
        console.log("Swift에서 받은 응답:", response);
    } catch (error) {
        console.error("Swift 응답 오류:", error);
    }
}

sendMessageToNative();

 

'iOS' 카테고리의 다른 글

[iOS] How to Play Video: AVFoundation, HLS, DRM, FPS, Chromecast  (0) 2025.03.23
[iOS] WebKit - WKNavigationDelegate  (1) 2025.02.23
[Swift] Ping 로직  (0) 2024.05.10
메모리 최적화 - iOS Memory Deep Dive  (1) 2024.02.23
[Swift] Profiling 방법  (0) 2024.02.20