Skip to content

Instantly share code, notes, and snippets.

@rmaafs
Last active November 17, 2023 00:12
Show Gist options
  • Save rmaafs/d8f12a204cac8ac55421dc40de241510 to your computer and use it in GitHub Desktop.
Save rmaafs/d8f12a204cac8ac55421dc40de241510 to your computer and use it in GitHub Desktop.
Communication between ReactJS WebPage and Swift App (WKWebView)
import useAppMessage from "./hooks/useAppMessage";
import "./App.css";
function App() {
const { appMessage, sendAppMessage } = useAppMessage(); // appMessage is the message received from the Swift APP
const handlePlay = () => {
sendAppMessage("Hello from page!");//Send message to the Swift APP
};
return (
<div className="App">
<header className="App-header">
<p>From Swift: {appMessage}</p>
<span onClick={handlePlay}>Play!</span>
</header>
</div>
);
}
export default App;
import SwiftUI
import WebKit
struct WebView: UIViewRepresentable {
let urlString: String = "http://localhost:3000"
class Coordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler {
var webView: WKWebView?
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.webView = webView
}
// Receive message
func userContentController(
_ userContentController: WKUserContentController,
didReceive message: WKScriptMessage
) {
print(message.body)
self.messageToWebview(msg: "Received at \(Date())")
}
func messageToWebview(msg: String) {
self.webView?.evaluateJavaScript("onAppMessage('\(msg)');")
}
}
func makeCoordinator() -> Coordinator {
return Coordinator()
}
func makeUIView(context: Context) -> WKWebView {
let coordinator = makeCoordinator()
let userContentController = WKUserContentController()
userContentController.add(coordinator, name: "bridge")
let configuration = WKWebViewConfiguration()
configuration.userContentController = userContentController
let _wkwebview = WKWebView(frame: .zero, configuration: configuration)
_wkwebview.navigationDelegate = coordinator
return _wkwebview
}
func updateUIView(_ webView: WKWebView, context: Context) {
if let url = URL(string: urlString) {
let request = URLRequest(url: url)
webView.load(request)
}
}
}
struct ContentView: View {
var body: some View {
VStack {
//Text("Web View Page")
WebView()
}
}
}
import { useEffect, useState } from "react";
const useAppMessage = () => {
const [appMessage, setAppMessage] = useState(null);
const sendAppMessage = (message) => { // Send message to the Swift APP
// eslint-disable-next-line
webkit.messageHandlers.bridge.postMessage(message);
};
useEffect(() => {
// Function for get message from Swift APP
function handleMessage(msg) {
setAppMessage(msg); // Edit the hook
}
// Assign the function to the global space.
window.onAppMessage = handleMessage;
// Clean up the assignment when the component is unmounted
return () => {
window.onAppMessage = null;
};
}, []); // Only runs once when the component mounts
return { appMessage, sendAppMessage };
};
export default useAppMessage;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment