iOS/Common

[Swift] 네이티브의 WKWebView와 웹의 JavaScript 간 통신 방법

TDCIAN 2023. 4. 14. 09:07

 

Q. iOS 애플리케이션 개발 과정에서 WKWebView를 사용할 때 JavaScript와 통신하는 방법에 대하여 Native는 Swift 코드로, Web은 JavaScript 코드로 설명해 줘

 

A. WKWebView를 사용하여 iOS 애플리케이션과 웹과 JavaScript를 통신하기 위해서는 'WKScriptMessageHandler' 프로토콜을 구현하고, 해당 핸들러를 사용하여 메시지를 보내고 받아야 합니다. 이를 설명하기 위해, 아래는 Swift 코드와 JavaScript 코드를 사용한 예시입니다.

 

1. 'WKScriptMessageHandler' 프로토콜을 채택하고 메시지를 처리하는 클래스를 생성합니다.

 

Swift

class MessageHandler: NSObject, WKScriptMessageHandler {
    func userContentController(
        _ userContentController: WKUserContentController, 
        didReceive message: WKScriptMessage
    ) {
        if message.name == "myMessageHandler" {
            print("Received message from web: \(message.body)")
            // Handle the message here
        }
    }
}

 

 

2. 'WKWebView' 인스턴스를 생성하고, 'WKUserContentController'를 이용해 핸들러를 등록합니다.

 

Swift

let configuration = WKWebViewConfiguration()
let userContentController = WKUserContentController()
let messageHandler = MessageHandler()
userContentController.add(messageHandler, name: "myMessageHandler")
configuration.userContentController = userContentController
let webView = WKWebView(frame: self.view.bounds, configuration: configuration)

 

 

3. 메시지를 보내기 위한 JavaScript 함수를 작성합니다.

 

JavaScript

function sendMessageToNative() {
    var message = { key1: "value1", key2: "value2" };
    window.webkit.messageHandlers.myMessageHandler.postMessage(message);
}

 

 

4. iOS에서 등록한 핸들러 이름과 동일한 이름을 가진 메시지 핸들러를 등록합니다.

 

JavaScript

window.webkit.messageHandlers.myMessageHandler.postMessage('Hello from web');

 

5. iOS에서 보낸 메시지를 처리하기 위한 이벤트 핸들러를 작성합니다.

 

JavaScript

window.addEventListener('message', function (event) {
    console.log('Received message from native:', event.data);
    // Handle the message here
});

위와 같은 방법으로 iOS와 웹 사이에서 메시지를 주고 받을 수 있습니다.

 

 

 

Q. 위 내용에 대한 예시로 활용할 수 있는 Swift 프로그램 코드와 JavaScript 프로그램 코드를 보여줘

 

A. 아래는 iOS에서 WKWebView를 사용하여 JavaScript와 통신하는 예시 코드입니다.

 

Swift

import UIKit
import WebKit

class ViewController: UIViewController, WKScriptMessageHandler {
    
    var webView: WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Create WKWebView configuration and userContentController
        let configuration = WKWebViewConfiguration()
        let userContentController = WKUserContentController()
        
        // Add script message handler to userContentController
        userContentController.add(self, name: "myMessageHandler")
        
        // Set the userContentController to configuration
        configuration.userContentController = userContentController
        
        // Create WKWebView with the configuration
        webView = WKWebView(frame: view.bounds, configuration: configuration)
        
        // Load the HTML file from the app bundle
        if let htmlPath = Bundle.main.path(forResource: "index", ofType: "html") {
            let url = URL(fileURLWithPath: htmlPath)
            let request = URLRequest(url: url)
            webView.load(request)
        }
        
        // Add WKWebView to view hierarchy
        view.addSubview(webView)
    }
    
    // Handle script messages received from WKWebView
    func userContentController(
        _ userContentController: WKUserContentController, 
        didReceive message: WKScriptMessage
    ) {
        if message.name == "myMessageHandler" {
            print("Received message from web: \(message.body)")
            // Handle the message here
        }
    }
    
}

 

JavaScript

// Send message to native
function sendMessageToNative() {
    var message = { key1: "value1", key2: "value2" };
    window.webkit.messageHandlers.myMessageHandler.postMessage(message);
}

// Handle message from native
window.addEventListener('message', function (event) {
    console.log('Received message from native:', event.data);
    // Handle the message here
});

 

iOS는 'WKScriptMessageHandler' 프로토콜을 구현하여 웹에서 iOS로 보낸 메시지를 처리합니다.

 

JavaScript에서는 'window.webkit.messageHandlers' 객체를 사용하여 웹에서 iOS로 메시지를 보냅니다.

그리고 'window.addEventListener' 메서드를 사용해서 iOS에서 웹으로 보낸 메시지를 처리합니다.

 

위 예시코드에서는 iOS측에서 'index.html' 파일을 로드하여 웹 페이지를 표시하도록 하였습니다.

이 파일은 앱 번들에 포함된 파일로, 앱 실행 시 함께 로드됩니다.

페이지 내에서 JavaScript 함수를 호출하거나, 이벤트를 감지하여 iOS와 메시지를 주고받을 수 있습니다.