모바일 앱이 필요했고 웹 화면은 이미 있었다. 웹을 감싸는 방식으로 가서 앱은 껍데기고 WebView 안에서 웹이 돈다.
빨리 나왔다. 그리고 몇 가지가 안 됐다.
Table of contents
제약 — 웹으로 안 되는 넷
써 보면서 하나씩 나왔고 모아 보니 네 가지로 갈렸다.
기기 기능 카메라·위치·파일 접근. 브라우저 권한으로 되는 것도 있고 안 되는 것도 있다
알림 앱이 꺼져 있을 때 보내려면 네이티브가 필요하다
오프라인 연결이 끊기면 아무것도 안 된다
저장 웹 저장소는 용량이 작고 지워질 수 있다
이 넷이 경계였다. WebView 안에서 해결되지 않으므로 앱 쪽에서 만들어 웹에 열어 줘야 하고 어떤 것이 이 넷에 해당하는지를 처음에 알았으면 계획이 달라졌을 것이다.
다리를 놓았다
웹과 네이티브 사이에 통로를 만들었다.
// 웹에서 부른다
Bridge.call('getLocation', {}, (result) => { ... });
네이티브가 그 요청을 받아 처리하고 결과를 돌려준다. addJavascriptInterface 로 객체를 하나 붙이면 웹 쪽 JavaScript 가 그것을 부를 수 있다.
Bridge 에 필요한 것만 하나씩 열었고 처음부터 다 만들지 않았다.
통로가 늘어나면
이것이 계속 늘면 결국 앱을 다시 만드는 것과 같아져서 기준을 뒀다.
웹으로 되면 웹으로 한다 통로는 안 될 때만
통로는 얇게 로직을 네이티브에 넣지 않는다
목록을 유지한다 어떤 통로가 있는지 문서로 관리
통로를 넓게 열어 두면 나중에 곤란해진다. 문서도 이 기능이 JavaScript 에게 앱을 제어할 힘을 준다고 경고하고 들어오는 HTML 이 전부 우리가 쓴 것일 때만 쓰라고 적는다.
다행히 좁히는 장치가 규격에 들어 있었다. targetSdkVersion 이 17 이상이면 @JavascriptInterface 를 붙인 메서드만 웹에서 보이고 안 붙인 것은 아예 안 불린다.
한 번 열어 준 것은 웹이 쓰기 시작하므로 닫기 어렵다. 통로는 얇게 두고 판단은 웹에서 하게 하니 앱을 다시 배포할 일이 줄었다.
버전이 갈렸다
가장 곤란했던 것이 이것이었다. 웹은 배포하면 즉시 반영되는데 APK 는 사용자가 업데이트해야 한다.
웹: 새 통로를 쓰는 코드로 갱신됨
앱: 옛 버전, 그 통로가 없음
→ 오류
웹이 앱보다 앞서 나가면 깨진다. 두 가지를 넣었다.
if (Bridge.version >= 3) { 새 기능 } else { 대체 동작 }
Bridge.version 으로 앱이 자기 버전을 알려주고 웹이 그것을 보고 기능을 켜고 끈다. 버전은 User-Agent 끝에 덧붙여 보내게 했다.
그리고 너무 낡은 앱은 업데이트를 요구하는 최소 버전을 강제했는데 이것은 마지막 수단이다. 두 배포 주기가 다르다는 것을 구조에 반영해야 했다.
화면이 어색했다
WebView 에 웹 화면을 그대로 넣으니 앱 같지 않았다.
뒤로 가기가 브라우저처럼 동작한다
스크롤이 튕긴다
링크를 누르면 브라우저가 열린다
하나씩 잡았다. 뒤로 가기는 goBack() 에 연결해 줘야 웹 화면 사이를 돌아간다.
Android 쪽에서 네이티브 감각을 흉내 내는 작업이 생각보다 많았고 이 부분에서 시간이 꽤 들었다. 처음에 웹이 있으니 금방이라고 본 것이 여기서 틀렸다.
그래도 이 방식을 고른 것은 화면이 많고 자주 바뀌기 때문이었다. 그것을 네이티브로 두 벌 만들면 유지가 안 된다.
대가는 네이티브 감각이 부족하고 기기 기능마다 Bridge 통로가 필요하고 버전이 갈린다는 것이다. 기준은 화면이 자주 바뀌는가였고 자주 바뀌면 웹이 유리하며 안 바뀌고 기기 기능이 많으면 네이티브가 낫다.
정리
- 웹을 감싸는 앱은 화면이 많고 자주 바뀔 때 유리하다
- 웹으로 안 되는 것은 기기 기능과 알림과 오프라인과 저장 넷이다
- 그 경계를 처음에 긋는 것이 순서다
- 통로는 필요한 것만 하나씩 열고 얇게 유지한다
- 로직을 네이티브에 넣지 않고 어떤 통로가 있는지 문서로 관리한다
@JavascriptInterface를 붙인 것만 웹에서 보인다- 한 번 열어 준 것은 닫기 어렵다
- 웹이 앱보다 앞서 나가면 깨진다
- 앱 버전을
User-Agent에 실어 보내면 웹이 보고 기능을 켜고 끈다 - 네이티브 감각을 흉내 내는 작업이 예상보다 많다
- 판단 기준은 화면이 자주 바뀌는가다