소리꽃 KeyBloom TIL 16
같은 코드인데 웹에서는 되고 앱으로 감싸면 안 되는 문제가 한꺼번에 셋 나왔다. 원인은 다 달랐지만 성격은 하나였다.
감싼 환경은 같은 코드를 다르게 돌린다
웹에서 됐다는 건 앱에서 된다는 뜻이 아니다
큐 순서를 끌어서 바꾸는 기능(드래그 앤 드롭)이 웹에서는 되는데 앱에서만 안 됐다. 앱을 감싸는 Tauri가 “파일을 창에 떨어뜨리면 받는” 기능을 기본으로 켜 두고 있었고, 그게 운영체제 단에서 드래그를 먼저 가로채 화면 안 드래그가 죽은 것이다. 설정 하나를 끄니 해결됐다.
고치는 건 한 줄이었는데, 이 부류는 찾는 데 시간이 든다. 코드를 아무리 봐도 웹에서는 잘 돌기 때문이다.
같은 코드로 웹과 앱을 동시에 내면 이런 자리가 반드시 생긴다. 그래서 확인은 두 군데서 따로 해야 하고, “웹에서 되는데 앱에서만 안 된다”는 제보가 오면 우리 코드보다 감싸는 틀(Tauri와 그 안에서 화면을 그리는 WebView2)을 먼저 의심하는 게 빠르다.
빌려 쓴 기본 UI를 직접 만들면 딸려 있던 것까지 만들어야 한다
색을 고르는 칸은 HTML이 기본으로 주는 <input type="color">를 썼다. 웹에서는 잘 뜨는데 앱에서는 WebView2가 운영체제 색 대화상자를 앱 바깥 별도 창으로 띄웠다. 위치를 우리가 정할 수가 없어서, 공연 중에 쓰기엔 곤란했다.
그래서 색 선택기를 앱 안에 직접 만들었다. 그런데 만들고 나니 원래 딸려 있던 것들이 같이 사라졌다는 걸 알게 됐다. 화면에서 색을 집어 오는 스포이드가 없어졌고, 되돌리기가 색 변경을 한 단계로 묶어 주던 것도 안 먹었다. 둘 다 따로 붙여야 했다.
기본으로 제공되는 요소를 직접 만든 것으로 바꿀 때 드는 비용은 그 요소를 그리는 일만이 아니다. 거기 무료로 딸려 오던 동작이 몇 개인지 먼저 세어 봐야 한다. 대개 생각보다 많고, 하나씩 빠뜨린 채로 출시되면 “예전엔 됐는데”라는 제보로 돌아온다.
준비됐다는 신호
로딩이 끝났다는 표시가 준비됐다는 뜻은 아니다
앱을 켤 때 로딩 막대가 다 차기를 기다렸는데도, 연주 모드에 들어가 첫 건반을 누르면 소리가 늦게 났다.
원인은 피아노 소리가 두 벌이라는 것이었다. 하나는 브라우저 오디오로 재생하는 용이고, 하나는 연주용 저지연 네이티브 엔진(Rust)용이다. 로딩 막대는 앞엣것만 기다리고 있었고, 뒤엣것은 연주 모드에 처음 들어갈 때 그제야 준비를 시작했다.
여기서 두 가지를 배웠다. 하나는 로딩 표시가 “무엇을” 기다리는지 명시적으로 정해야 한다는 것이다. 시간이 지나면 준비할 것이 늘어나는데, 로딩 막대는 처음 만들 때 넣은 것만 계속 기다린다.
다른 하나는 “시작했다”는 응답과 “끝났다”는 응답이 다르다는 것이다. 준비를 시켰더니 곧바로 응답이 왔는데, 그건 준비를 시작했다는 뜻이지 끝났다는 뜻이 아니었다. 실제로 끝났는지 알려면 결과로 채워지는 값을 봐야 했다.
기다림을 설계할 때는 “무엇이 채워지면 진짜 끝난 것인가”를 정하고 그걸 기준으로 삼아야 한다. 호출이 돌아온 것을 완료로 쓰면 조용히 어긋난다.
요약
- 웹에서 됐다고 앱에서 되는 게 아니다 — 감싸는 틀이 같은 동작을 가로챌 수 있다
- “앱에서만 안 된다”는 우리 코드보다 감싸는 틀을 먼저 본다
- 기본 UI를 직접 만들 땐 거기 무료로 딸려 오던 동작을 먼저 세어 본다
- 로딩 표시가 무엇을 기다리는지 명시한다 — 준비할 것은 늘어나는데 표시는 안 따라간다
- “시작했다”와 “끝났다”는 다르다. 무엇이 채워지면 끝인지를 정해 두고 그걸 기준으로 기다린다