์๋ก
ํ์๊ฐ์
ํ์ด์ง๋ฅผ ํ๋ก ํธ์์ ๋ฆฌ์กํธ๋ก ์ ์ํ๋ค. ์ฌ์ค์ ์ฐ๋ฆฌ ํ๋ก๋ํธ ์๋๋ฆฌ์ค์ ๋ฐ๋ฅด๋ฉด ํ์๊ฐ์
ํ์ด์ง๋ ๋ชจ๋ฐ์ผ ์ฑ ๋ด๋ถ์ ์น๋ทฐ๋ก ๋์์ง๋ ๋ชจ๋ฐ์ผ์ ์ข
์๋ ํ๋ฉด์ด๋ค. ๊ทธ๋ ์ง๋ง ๋ชจ๋ฐ์ผ ์ฑ์ด ๊ฐ๋ฐ๋๊ธฐ ์ด์ ์ ์นํ์ด์ง์ ์์ฒด์์๋ ํด๋น ๊ธฐ๋ฅ๋ค์ด ๋
๋ฆฝ์ ์ผ๋ก ๋์ํ ์ ์๋๋ก ์น์์์ ์์์ ์ธ ์๋๋ฆฌ์ค๋ก ํด๋น ํ์ด์ง๋ฅผ ๋ง๋ค์๋ค.
๊ทธ๋ฆฌ๊ณ ๋ชจ๋ฐ์ผ ์ฑ ๊ฐ๋ฐ์ด ์์ฑ๋๊ณ , ๋ด๊ฐ ๋ง๋ค์ด๋์ ์นํ์ด์ง๋ฅผ ์น๋ทฐ๋ก ์ฌ๋ฆฌ๋ ์์
์ ํ๋ค.
๊ฐ๋ฐ ํ๊ฒฝ
๋ชจ๋ฐ์ผ: flutter, ์น๋ทฐ ํจํค์ง flutter inappwebview
์นํ๋ก ํธ: react
์ด์ ๋ด๊ฐ ์ ์ํ ์นํ์ด์ง๊ฐ ์๋์ ๊ฐ์ด ๋ ๊ฐ์ง ์๋๋ฆฌ์ค๋ก ๋๋๊ฒ ๋ ๊ฒ์ด๋ค.
1. ๋ชจ๋ฐ์ผ ์น๋ทฐ์์ ๋์์ก์ ๋
2. regular ์น ๋ธ๋ผ์ฐ์ ์์ ๋์ํ ๋
๋ฐ๋ผ์ ๊ธฐ์กด ๋ฆฌ์กํธ ํ์ด์ง๊ฐ ๊ธฐ๋ณธ ์น๋ธ๋ผ์ฐ์ ์์ ์คํ๋๊ณ ์๋์ง ์น๋ทฐ์์ ์คํ๋๋ ์ง๋ฅผ javascript๋ก ๊ฐ์งํด์ผํ๋ค.
๋ฐฉ๋ฒ1 - Web API์ ๊ธฐ๋ณธ userAgent ์ ๋ณด๋ก ๋์ค๋ ๋ฌธ์์ด๋ก ๊ฐ์ง
๊ตฌ๊ธ๋ง์ ํด์ stackoverflow์ ๋์์ผ๋ก ๋ธ๋ผ์ฐ์ ๊ฐ ๊ฐ์ง๊ณ ์๋ userAgent ์ ๋ณด๋ก ์น๋ทฐ๋ฅผ ํ๋ณํ๋ ๋ฆฌ์์ค๋ฅผ ์ฐพ์ ์ ์ฉํ๋ค.
์ด ํจ์๋ฅผ ๋ฆฌ์กํธ ์ฝ๋ ์์์ ์ฌ์ฉํด์ ์น๋ทฐ์ด๋ฉด ์ฒ๋ฆฌํด์ผ ํ๋ ๋ก์ง์ ์์ฑํ๋ค.
์น๋ทฐ์ธ์ง ๊ฐ์งํ๋ ํจ์
export function isWebView() {
const navigator = window.navigator;
const userAgent = navigator.userAgent;
const normalizedUserAgent = userAgent.toLowerCase();
const isIos =
/ip(ad|hone|od)/.test(normalizedUserAgent) ||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
const isAndroid = normalizedUserAgent.includes('android');
const isSafari = normalizedUserAgent.includes('safari');
const isWebview =
(isAndroid && normalizedUserAgent.includes('; wv)')) ||
(isIos && !('standalone' in navigator) && !isSafari);
return isWebview;
}
๊ฒฐ๋ก ์ ์ผ๋ก ์ด ์ฝ๋์ ๋ฌธ์ - ios์์๋ ๋จนํ์ง ์๋๋ค. (์๋๋ก์ด๋ ์ฑ๋ง ์ฌ์ฉํ๋ค๋ฉด ์ ์ฝ๋๋ก๋ง ์น๋ทฐ๋ฅผ ํ๋ณํ ์ ์๋ค.)
๋ธ๋ผ์ฐ์ ์์ฒด๊ฐ ๊ฐ์ง๊ณ ์๋ userAgent ์ ๋ณด๋ก ์น๋ทฐ๋ฅผ ํ๋ณํ๋ ์ฝ๋์ด๋ค.
๊ทธ๋ฐ๋ฐ ๊ด๋ จ ์ฝ๋๊ฐ ๋ณดํต 10๋ ์ ์ฝ๋๊ฐ ๋ง๊ณ , ios ์ฝ๋์ ๊ฒฝ์ฐ์๋ ์ safari ๋ธ๋ผ์ฐ์ ๋ฅผ ์ ์ธํ๋๊ฑด์ง ์ดํดํ ์ ์์ด ์ฐ์ฐํ์ง๋ง ์ฐ์ ์๋๋ก์ด๋ ์๋ฎฌ๋ ์ดํฐ๋ฅผ ๋๋ ค์ ํ ์คํธํ์๋ ์ ์๋๋์๋ค.
๊ทธ๋ฆฌ๊ณ ์๊ฐ์ด ํ๋ฌ…๋ชจ๋ฐ์ผ ๊ฐ๋ฐ์ ์ ๋ฐฐ๊ฐ ios ๋ชจ๋ฐ์ผ ํ๊ฒฝ์์ ๋๋ ค๋ณด๊ณ ๋... ios์์ ์๋๋๋ฐ??? ํ๋ค
๊ทธ๋์ ๋ค๋ฅธ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ฐพ์์ผํ๋ค.
ios device ํฌ๊ธฐ๋ฅผ ๊ฐ์งํด์ ๋๋ฐ์ด์ค ๋ง๋ค ๊ณ ์ ํ ๋๋น, ๋์ด๊ฐ์ผ๋ก ์น๋ทฐ๋ก ํ๋ณํ๋ ์ฝ๋, safari๊ฐ ์๋์ง ํ์ ํ๋ ์ฝ๋ ๋ฑ๋ฑ์ด ์์์ง๋ง ๊ทธ๋ฅ ์ข์ ๋ฐฉ๋ฒ์ด ์๋ ๊ฒ ๊ฐ์๋ค.
๋ฆฌ์์น๋ฅผ ํด๋ณด๋ ๋ค์ดํฐ๋ธ ๋ชจ๋ฐ์ผ ์ฑ์์ userAgent ์์ฑ์ ๋ฐ๊ฟ์ฃผ์ด ์๋๋ก์ด๋ ios ๋ ๋ค ์น๊ณผ ์น๋ทฐ๋ฅผ ๊ตฌ๋ณํ ์ ์๋ ๋ฐฉ๋ฒ์ด ์์๋ค. ์ด๊ฑธ ๋ณด๊ณ ํ ..? ๋ชจ๋ฐ์ผ์์ userAgent ์์ฑ์ ๋ฐ๊ฟ์ฃผ๋ฉด ๋ ๊ฒ๋ ๊ฐ์๋ฐ? ๋ผ๋ ์๊ฐ์ด ๋ค์๋ค.
๊ทธ๋์ ๋ชจ๋ฐ์ผ ๊ฐ๋ฐ์ ์ ๋ฐฐํํ ์ ์์ ํด๋ณด๋๋ฐ...
๋ฐฉ๋ฒ2 - ๋ชจ๋ฐ์ผ์์ ์ค์ ํ userAgent ๊ฐ์ผ๋ก ๊ฐ์ง
์ค!! ์ฐ๋ฆฌ ๋ชจ๋ฐ์ผ์ flutter inappwebview ํจํค์ง๋ฅผ ์ฌ์ฉํด์ ์น๋ทฐ ํต์ ์ ํ๋๋ฐ, ์ฌ๊ธฐ์์ userAgent๋ฅผ ๋ฐ๋ก ์ค์ ํ ์ ์๋ค๋ ๊ตฟ๋ด์ค๊ฐ ์๋ค.
๊ทธ๋์ ์๋ก ํฉ์ํด์ ์ ํ ์๋ก์ด ์ด๋ฆ์ผ๋ก userAgent ๊ฐ์ผ๋ก ์ฐ๊ฒ ๋ค๊ณ ์ฝ์ํ๊ณ , ๋ชจ๋ฐ์ผ์์ ํด๋น userAgent ์ ๋ณด๋ฅผ ์ค์ ํ๋๋ก ํ๋ค.
์ฐ๋ฆฌ๋ `์ฐ๋ฆฌ์ฑ์ด๋ฆ_APP_WEBVIEW`๋ผ๋ ๋ฌธ์์ด๋ก ์ ํ๋ค. (์ฝ๋์ ํธ์์ `APP_WEBVIEW` ๋ผ๊ณ ํํ)
๋ชจ๋ฐ์ผ ๊ฐ๋ฐ์ํํ
์ฝ๋ ๋ณด์ฌ๋ฌ๋ผ๊ณ ์ซ๋ผ์ ๋ฐ์๋ธ ํ๋ฌํฐ ์ฝ๋
InAppWebViewSettings _configureWebViewSetting() {
return InAppWebViewSettings(
userAgent: 'APP_WEBVIEW', //๋ชจ๋ฐ์ผ๊ณผ ํฉ์ํด์ ๋ง๋ ์ด๋ฆ
verticalScrollBarEnabled: false,
horizontalScrollBarEnabled: false,
supportZoom: false,
overScrollMode: OverScrollMode.NEVER,
disallowOverScroll: true,
alwaysBounceVertical: false,
disableInputAccessoryView: true,
);
}
์ด์ ํ๋ก ํธ js ์ฝ๋์ ์น๋ทฐ ํ๋ณ ํจ์๋ฅผ ๋ฐ๊ฟ์ค๋ค.
์ฐ๋ฆฌ๊ฐ ์ ํด๋ ๊ฐ์ด ๋ธ๋ผ์ฐ์ ๋จ์ Web Api์ userAgent ์์ฑ์ ํฌํจ์ด ๋์ด์๋์ง ํ์ธํ๋ ์์ฃผ ๊ฐ๋จํ ํจ์๋ค.
๋ธ๋ผ์ฐ์ ์ userAgent ๊ฐ์ 'APP_WEBVIEW' ๋ฌธ์์ด์ด ํฌํจ๋์ด์์ผ๋ฉด true๋ฅผ, ์์ผ๋ฉด false๋ฅผ ๋ฐํํ๋ค.
export function isWebView() {
const USER_AGENT_NAME = 'APP_WEBVIEW';
return window.navigator.userAgent.includes(USER_AGENT_NAME);
}
๋ก๊ทธ๋ก ํ ๋ฒ ๋ชจ๋ฐ์ผ์์๋ ์ ์ฐํ๋์ง userAgent ์ ๋ณด๋ฅผ ํ์ธํด๋ณด์๋ค.
console.log(window.navigator.userAgent, '์ ์ ์์ด์ ํธ ์ ๋ณด');
1. ์น ๋ธ๋ผ์ฐ์ ์ ๊ฒฝ์ฐ
์น ๋ธ๋ผ์ฐ์ ์ userAgent ์ ๋ณด๋ฅผ ํ์ธํด๋ณด๋ฉด ์๋ ์บก์ฒ ํ๋ฉด์ฒ๋ผ ๋์จ๋ค. ์น๋ทฐ๊ฐ ์๋๊ธฐ๋๋ฌธ์ ์๋ ๊ธฐ์กด ๋ธ๋ผ์ฐ์ ๊ฐ ๊ฐ์ง๊ณ ์๋ ์ ๋ณด๊ฐ ์ ์ฐํ๋ค.
2. ๋ชจ๋ฐ์ผ ์ฑ๋ทฐ์ ๊ฒฝ์ฐ
์ฝ๋๊ฐ ๋ชจ๋ฐ์ผ ์น๋ทฐ์์ ๋์์ง๋ฉด?? ์๋์ฒ๋ผ ๋ก๊ทธ๊ฐ ์ฐํ๋ค.
WebView ID 1 calling "onConsoleMessage" using {message: APP_WEBVIEW ์ ์ ์์ด์ ํธ ์ ๋ณด, messageLevel: 1}
๋ชจ๋ฐ์ผ์์ ์น๋ทฐ๋ฅผ ๋์ฐ๋ฉด ํ์ด์ง ๋ก๋ํ ๋ ํค๋๊ฐ์ ์๋์ ๊ฐ์ด ๋์จ๋ค๊ณ ํ๋ค.
headers: {Accept-Language: ko-KR,ko;q=0.9, Sec-Fetch-Mode: navigate, Sec-Fetch-Dest: document, Sec-Fetch-Site: none, Accept-Encoding: gzip, deflate, br, Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8, User-Agent: APP_WEBVIEW}, attribution: 0, cachePolicy: 0, body: null...}
๋ชจ๋ฐ์ผ์์๋ ์ด์ userAgent ๋ธ๋ผ์ฐ์ ์ ๋ณด๊ฐ ์์ ์ค์ ํด๋ ๊ฐ์ธ `APP_WEBVIEW`๋ก ๋ณ๊ฒฝ๋์์์ ํ์ธํ ์ ์๋ค.!!
๋ฐ๋ผ์ ๋ชจ๋ฐ์ผ์์ ์ค์ ํ userAgent ์์ฑ๊ฐ์ด ์์ผ๋ฉด ์น๋ทฐ ํ๋ฉด์ธ ๊ฒ์ด๊ณ ์๋๋ฉด ์ผ๋ฐ ๋ธ๋ผ์ฐ์ ํ๋ฉด์ผ๋ก ๊ฐ์งํด์ ๊ตฌ๋ถํ ์๊ฐ ์๋ค!
๋ ํผ๋ฐ์ค
https://developer.mozilla.org/en-US/docs/Web/API/Navigator/userAgent
https://stackoverflow.com/questions/75425363/how-to-detect-webview-in-javascript-for-ios-and-android
https://developer111.tistory.com/37
https://inappwebview.dev/docs/webview/in-app-weview-settings/