웹 페이지 하나를 개발해서 안드로이드, IOS, 모바일 웹, 데스크탑 웹에 대응할 수 있다.
모바일 앱의 경우 업데이트하고 배포하기 까지 상당히 많은 시간이 소요됩니다. 이러한 과정 없이 웹뷰를 사용하면 바로 업데이트가 가능합니다.
웹 뷰에서는 사전에 정의된 인터페이스를 통하여 네이티브 기능 일부를 사용할 수 있습니다.
가장 빠른 네이티브 기능을 사용하다가 웹뷰를 만나면 느려지는 것을 느낄 수 있습니다.
웹뷰에서 일어나는 몇 가지 보안 이슈가 있습니다.
매년 안드로이드와 IOS 신기능은 업데이트되지만 네이티브에서는 사용할 수 있어도 웹뷰에서는 사용하지 못하는 것들이 많습니다.
단점보다 강력한 장점 때문에!
다양한 기능을 하나로 패키징하기 제일 쉽습니다. 모바일 앱이 커질수록 모바일 개발자를 구하기가 어려운데요. 이를 극복하기 위해 웹뷰를 사용하는 경우도 많습니다.
웹뷰를 사용하면 작은 변화 또는 피드백을 빠르고 쉽게 확인할 수 있습니다.
슈퍼앱에서는 플랫폼 기능을 제공하는데요. 자사 서비스 외에 서드파티 기능을 제공하여 묶을 때에도 웹뷰를 사용합니다.
자사 서비스내에 네이티브 코드가 외부에서 들어온다면 서비스 코드의 유출 리스크도 있을 것이고 외부 앱 코드의 안정성도 문제가 될 것입니다. => 웹뷰를 사용해서 문제 해결
APP은 웹뷰가 왜 이렇게 동작하는지를 알 수 있고, FE는 웹스펙의 구현이 이렇구나를 알 수 있어요.
WebKit - 애플에서 개발한 웹 엔진, Safary 브라우저와 아이폰에서 동작하는 웹 뷰가 WebKit에 의해 동작하고 있습니다.
Chromium - 구글에서 개발한 웹 웬진, Chrome 브라우저와 안드로이드 모바일 웹뷰, 다양한 셋탑박스, 자동차에서 돌아가는 안드로이드 오토, VSCODE도 Chromium을 사용하고 있습니다.
JavaScriptCore는 WebKit이 구현한 자바스크립트 엔진에 대한 구현 코드가 담겨있습니다.
WebCore는 HTML, CSS같은 웹 스펙 구현 코드가 담겨있습니다.
WebKit은 이러한 웹 엔진들이 돌아갈 수 있는 실질적인 코드들입니다.
WebKit은 WebProcess, GPUProcess, NetworkProcess, UIProcess로 나눌 수 있습니다.
WebProcess는 WebCore가 돌아가는 Process 코드가 있으며, GPUProcess는 렌더링에 관련된 코드들, NetworkProcess는 네트워크를 연결하여 데이터를 받아오는 코드들, UIProcess는 애플리케이션 레이어입니다.
UIProcess는 맥과 IOS가 함께 사용하는 UI 프레임워크인 Cocoa와 아이폰에서 사용하는 ios 포트가 있습니다.
android_webview는 안드로이드 웹뷰에 대한 구현 내용들,
chrome은 chrome 브라우저에 대한 구현 내용들,
content는 chromium의 api 레어이이고,
net은 network에 대한 내용을 담고 있습니다.
v8은 chromium이 가지고 있는 자바스크립트 엔진 구현 코드입니다.
components는 chromium 브라우저들의 공통 요소들을 담고있습니다.
third_party는 blink라는 렌더링 엔진을 가지고 있습니다.
APP 개발자가 밝히는 뒷 이야기
아이폰에서 인스펙터가 안돼요.
안드로이드는 되는데요. 도와주세요.
애플에서 지원하지 않아요.
개발자 계정에 등록된 기기에서만 동작해요.
그럼 제 아이폰도 등록해주세요.
테스트 기기는 빌려 갈 수 있죠?
기기 등록수 제한이 있어서 힘들어요.
네, 그런데 개발 빌드만 인스펙터를 쓸 수 있어요.
불편해서 못참겠어요. 제가 앱 빌드 해볼게요.
Xcode는 이 버전으로 설치해 주세요,
ruby, gem은 저 버전이 필요하고, tuist 설치하구요.
iOS 16.4부터는 안드로이드처럼 됩니다.
애플 실리콘에서도 할 수 있습니다.
(FE 개발자라면 너무 쉬울 거에요. 대신 APP 개발자에게 알려주세요.)
모바일 앱은 일반적으로 싱글프로세스로 동작합니다. 따라서 멀티프로세스라고 하면 비동기 API 이슈가 발생할 수 있습니다.
멀티프로세스가 낮설냐? 그것은 아니고 위젯 서비스 형태를 해보았다면 멀티프로세스를 이해할 수 있습니다.
위젯과 앱이 데이터를 어떻게 주고받을 수 있으셨나요? 어떤 특정한 코드를 사용하셨을 겁니다. 이러한 부분을 생각하시면 앱과 웹뷰가 어떻게 데이터를 주고받을 수 있을지 이해할 수 있을 겁니다.
사파리처럼 무언가를 해달라고 하거나, 웹뷰에 대해서 어떤 데이터 통신이 필요없다 하면, 간단한 웹뷰로 보이게만 하면 된다면 SFSafariViewController를 사용해볼 수 있습니다.
그렇다면 Safari 웹 엔진을 가져와서 웹뷰가 아닌 웹 컨텐츠를 보여줄 수 있고, Safari에 입력된 암호 입력이나 여러가지 특징적인 것들을 함께 사용할 수 있습니다.
이슈 분석은 누가 먼저하게 될까요? 아마도 앱 개발자일 겁니다. 해당 이슈가 앱인지 웹인지 빨리 구분해주는 것이 좋습니다.
쿠키 이슈입니다. 프로세스가 다르기 때문에 쿠키라는 것은 사실 파일로 저장되고 있어서 파일이 서로 다른 경로 저장된다고 하면 서로 다른 형태의 쿠키 데이터를 읽고 쓸 수 있습니다.
앱이 쿠키를 쓰면? 웹에 동기화 시켜주기
웹이 쿠키를 쓰면? 앱에서 가져오기
// 1. 아주 위험
var woowacon = 2023;
// 2. 덜 위험
let woowacon = 2023;
// 3. 추천
(function () {
let woowacon = 2023;
})();
// 1. 레거시
try { woowacon(); } catch {}
// 2. 개선
if (typeof woowacon !== "undefined" && woowacon) {
woowacon();
}
if (typeof woowacon !== "undefined" && woowacon && woowacon.hasOwnProperty("show")) {
woowacon.show();
}
// 1. 웹 로그를 네이티브로 가져오기
let originalLog = console.log();
console.log = function(...args) {
woowacon.send({ event: "console.log", message: args });
originalLog.apply(console, args);
};
// 2. history.back에 기능 추가하기
let originalBack = window.history.back;
window.history.back = function () {
woowacon.send({ event: "history.back"});
originalBack.call(history);
};
웹뷰를 쓰면서 겪는 쉬운 문제부터 기상천외한 사건까지
2개를 호출했는데, 1개만 동작해요.
이러한 문제를 해결하기 위한 가장 간단한 방법은 앱스킴을 연달아 실행할 때 딜레이를 주는 방법이지만 더 나은 방법은 뒤에 알아보도록 하겠습니다.
앱 네이트브와 자바스크립트 문자열 차이
RFC 6265 (Cookie Limits)
Cookie 리미트가 넘어서 생겼던 문제 만약 이런 에러가 발생하면 Cookie를 삭제하고 새로고침하는 방식으로 해결
브라우저에서 혹은 웹엔진에서 임의의 캐시를 진행합니다. 이 페이지의 배포는 최소 2주전이 진행되어야 함을 공유하고 캐시를 하지 않아도 no-cache와 다양한 설정들을 추가하여 해결
FE 개발자, APP 개발자 모두 영차영차. 회사로 돌아가면 함께 해요.
URL 형태로 구성되어 있다.
woowacon://webview/hello?year=2023
호출 길이에 제한이 있습니다. 보통 2000~3000자
앱과 사전에 정의한 자바스크립트를 호출하는 모던한 방법
앱스킴과 다르게 호출 길이 제한이 없음
URL 로딩을 시도하지 않음
앞에서 살펴봤던 앱 스킴을 연달아 호출했을 때 생기는 문제 또한 JavaScript Interface를 통해 해결할 수 있습니다.
// 1. 앱스킴 호출
location.href = "woowacon://action?title=woowacon";
// 2. 자바스크립트 인터페이스 호출
woowacon.action("woowacon");
// 3. 변경사항으로 신규 매개변수: year
// 4. 앱스킴 호출
location.href = "woowacon://action?title=woowacon&year=2023";
// 5. 자바스크립트 호출
woowacon.action("woowacon", "2023")
let data = {
"title": "woowacon",
"year": 2023
}
let encoded = encodeURIComponent(JSON.stringify(data));
// 1. 앱스킴 호출
location.href = "woowacon://action?data=" + encoded;
// 2. 자바스크립트 인터페이스 호출
woowacon.action(JSON.stringify(data))
// 1. 앱스킴 호출
location.href = "woowacon://action?callback=<function_name>";
// 2. 자바스크립트 호출의 경우
woowacon.action("<callback_function_name>")
콜백함수의 동적 정의를 제거하고 사전 정의로 바꿔야합니다.
// 웹에서 알려준 함수를 호출
woowacon.action("hello")
wibdow.dispatchEvent(
new CustomEvent("woowacon", {
detail: {
title: "webview",
year: 2023
}
})
)
앱에서 개발자 도구를 볼 수 있는 라이브러리네요.
이번 영상은 웹뷰에 대한 내용이었는데요. 평소에 웹뷰에 대한 관심이 있어서 프론트엔드 개발자의 섹션은 아니였지만 시청했습니다. 발표의 주제가 앱개발자가 웹뷰를 만들 때 프론트엔드 개발자와 어떻게 개발을 하는 것이 좋을까? 라는 주제가 대부분이기 때문에 저같은 프론트엔드 개발자한테 맞는 영상은 아닌 거 같습니다. 하지만 웹과 모바일이 어떻게 다르고 이러한 차이에서 일어나는 문제와 해결 방법을 설명해주시는 부분은 많은 도움이되었고 추후에 웹뷰를 만들게된다면 참고를 많이할 거 같습니다.