728x90
๐ Webview PostMessage
ํ์ฌ์์ ์ฑ์ ๊ฐ๋ฐํ ๋ React-Native webview๋ก React ํ๋ก์ ํธ๋ฅผ ์์์ ์ฑ ๋ฑ๋ก์ ํ์๋ค.
๊ทธ๋ RN -> React ๋๋ React -> RN ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํด์ผํ๋ ์ผ์ด ์๊ธด๋ค.(์ฑ์ ์ผฐ์ ๋ osํ์ธ์ ํ๊ฑฐ๋, ์ ์ ์์น๋ฅผ ํ์ธํด react์์ ์ฌ์ฉํ ๊ฒฝ์ฐ ๋ฑ)
๊ทธ ๋น์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๊ธฐ๋กํด ๋์ผ๋ ค๊ณ ํ๋ค.
๐ React-Native Webview ์ต์ ์ธํ
React-Native webview ์์
์ onMessage
์์ฑ์ react์์ ๋ณด๋ด๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ๋ ์ฌ์ฉํ ํจ์๋ฅผ ์ ๋๋ค.
const webview = useRef();
<WebView
style={{backgroundColor: "#000"}}
overScrollMode="never"
ref={webview}
mixedContentMode={'always'}
mediaPlaybackRequiresUserAction={false}
javaScriptEnabled={true}
domStorageEnabled={true}
startInLoadingState={true}
originWhitelist={['*']}
allowsInlineMediaPlayback={true}
injectedJavaScript={debugging}
onNavigationStateChange={onNavigationStateChange}
// onMessage setting
onMessage={(e) => {
web_to_native(e)
}}
source={{
uri: uri,
}}
/>
๐ React-Native -> React
React-Native(๋ณด๋ด๊ธฐ)
// type, data ์ ์ก (react์์ ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ type์ผ๋ก ๊ตฌ๋ถํ๊ธฐ ์ํจ)
await webview.current.postMessage(JSON.stringify({
type: 'type',
data:{
key1: "postData1",
key2: "postData2"
}
}));
React(๋ฐ๊ธฐ)
const listenerData = () => {
const {key1, key2} = data;
}
const receiveMessage = (event) => {
// ๋ฐ์ ๋ฐ์ดํฐ(type, data)
const {type, data} = JSON.parse(event.data);
if(type ==='type'){
// ๋ง๋ค์ด ๋์ ํจ์์ data ์ ์ก
listenerData(data)
}
}
useEffect(() => {
// ios
window.addEventListener('message', receiveMessage);
// aos
document.addEventListener('message', receiveMessage);
return() => {
// ios
window.removeEventListener('message', receiveMessage);
// aos
document.removeEventListener('message', receiveMessage);
}
}, []);
๐ React -> React-Native
React(๋ณด๋ด๊ธฐ)
export const postNativeMessage = async(message, callback) => {
return new Promise((resolve, reject) => {
if (window.ReactNativeWebView) {
const listener = async(event) => {
// setIsChecked(data)
clearTimeout(timer);
/** android */
document.removeEventListener('message', listener);
/** ios */
window.removeEventListener('message', listener);
resolve(JSON.parse(event.data).result);
};
window.ReactNativeWebView.postMessage(message);
const TIMEOUT = 10000;
const timer = setTimeout(() => {
/** android */
document.removeEventListener('message', listener);
/** ios */
window.removeEventListener('message', listener);
reject('TIMEOUT');
}, TIMEOUT);
if(callback){
/** android */
document.addEventListener('message', listener);
/** ios */
window.addEventListener('message', listener);
}else {
clearTimeout(timer);
return
}
} else {
return
}
})
}
// ์ฌ์ฉ
await postNativeMessage(JSON.stringify({type: "type1", data: ''}), true);
React-Native(๋ฐ๊ธฐ)
const web_to_native = async (e) => {
const {type, data} = JSON.parse(e.nativeEvent.data);
if (type === "type1") {
// ์คํ ๋ก์ง
console.log(data);
}
}
728x90