자유
모바일 기기를 그래픽 타블렛으로 바꿔주는 VirtualTablet: Bluetooth 개발기
조회 3,348 · 공감 3 · 댓글 7
안녕하세요. 종종 개인 앱 개발하고 개발기 올리러 오는데, 이번에 AI 에이전트 코딩 시대를 맞이하여 간만에 개발기를 하나 들고 왔습니다.
예전에는 혼자서 끙끙 앓으며 개발했다면, 이번에는 Claude Code라는 든든한 파트너와 함께하며 느낀 점들을 공유해 봅니다.
개발하게 된 계기
사실 10년 전쯤 개발해서 유지보수해오던 VirtualTablet이라는 앱이 있었습니다.
이 앱만 있으면 와콤 태블릿 같은 하드웨어를 별도로 구매하지 않아도, 기존에 집에서 쓰던 갤럭시 탭이나 갤럭시 노트/울트라 같이 S Pen 지원하는 장치를 PC에 연결해서 태블릿 처럼 쓸 수 있게 해 줍니다.
기술적으로 보면 안드로이드 폰의 S Pen 입력을 받아서 PC로 전달하면, 윈도우나 맥 서버가 이를 수신해서 입력을 발생시키는 방식이었죠. (WiFi/USB 기반의 TCP 방식으로 통신했었습니다)
그런데 이게 혼자서는 유지보수가 쉽지 않은 앱이었습니다. 클라이언트/서버 양쪽을 다 멀티플랫폼으로 관리해야 하는데다, 특히 윈도우 서버는 가상 HID 장치 관리를 위해 드라이버 프로그래밍까지 건드려야 해서 업데이트가 매우 어려웠습니다.
그러다 작년쯤, 안드로이드 9.0 이상부터 BluetoothHidDevice 기능을 쓸 수 있다는 사실을 알게 되었습니다. 이걸 이용하면 PC(윈/맥/리눅스)에 별도 서버 프로그램을 설치할 필요 없이, 안드로이드 앱만으로 PC에 연결해서 무선 입력장치처럼 쓸 수 있더군요. (iOS도 비슷한 방식이 가능하고요.)
사실을 알게 된 건 좋았는데, 실제 디바이스에서 동작하게 만들기까지는 그야말로 무수한 삽질의 연속이었습니다. 회사 일 하랴, 육아 하랴... 바쁜 상황이라 진도가 도통 안 나가더군요. 테스트용 네이티브 안드로이드 앱으로 기본 동작만 겨우 확인해 둔 상태로 시간이 흘렀습니다.
그러다 올해 중순부터 Claude Code를 쓰기 시작하면서 개발 속도에 탄력이 붙었습니다.
- 나중에 iOS/Android 둘 다 지원하는 게 목표라 과감히 Flutter를 선택했습니다.
- 네이티브 개발 경험은 많지만 Flutter는 처음이었는데, 그냥 Claude Code만 믿고 시작했습니다.
- 초기에는 툴 사용법도 잘 몰라 헤맸지만, 결과적으로 AI와 함께 빠르게 공부 + AI 에이전트 코딩의 도움으로 엄청나게 빠르게 적응했습니다.
- Claude Code 없이 혼자 했다면 최소 1년은 걸렸을 작업인데, 2개월만에 출시하는데 성공했습니다. 심지어 기존 앱보다 결과물 퀄리티도 훨씬 좋습니다.
- 심지어 기존 앱은 4개국어 지원했는데, 이번에는 15개 국어를 지원합니다. LLM의 도움으로 아마 지원 언어를 무한히 늘릴 수 있을거같아요.
VirtualTablet: Bluetooth 초기 개발 프로젝트 셋업 과정
최대한 초기 프로젝트 시작할 때 체계적으로 접근하려고 노력했습니다.
Spec 문서 기반의 AI 개발
- 만들고자 하는 앱의 대략적인 요구사항을 제가 마크다운으로 작성합니다.
- Claude Code에게 이 문서를 주고, 더 구체적인 요구사항으로 보완해달라고 시킵니다.
- 보완된 문서를 제가 검토/수정한 뒤, 다시 Claude에게 "이걸 보고 단계별 개발 계획(Task List)을 짜와라"고 시킵니다.
- 작업 목록이 나오면, 한 번에 너무 많은 양을 시키지 않고 단계별로 끊어서 지시합니다. (한 번에 너무 큰 범위를 시키면 컨텍스트가 꼬여서 결과물이 엉망이 되더라고요.)
시행착오와 'CLAUDE.md'의 중요성
처음에는 위 방식대로 코드를 뽑아냈는데, 나름 스펙을 정확하게 줬으니 체계적으로 코드가 작성되었을거라 기대했지만, 겉만 번지르르하고 속은 중구난방이었습니다. 코드 컨벤션도 없고 상태 관리 일관성도 없어서 기능을 추가할 때마다 버그가 터졌습니다.
결국 잠시 멈추고 AI에게 물어가며 상태 관리 라이브러리로 Riverpod을 선택했습니다. 문제는 Claude Code가 자꾸 Deprecated 된 Riverpod 2.x 대 코드를 짜주는 겁니다. 최신(3.x) 문서를 학습하지 못 한 상태로 보였습니다.
이걸 해결하기위해 context7 MCP를 사용해 riverpod 최신 문서를 가져오게 하고, 프로젝트 루트에 CLAUDE.md 파일을 만들어 Riverpod Best Practice를 300라인 정도로 정리해서 넣어줬습니다. (AI가 자주 실수하는 부분 위주로 예제 코드를 여러개 넣었습니다.)
이렇게 셋업 하니 그제야 안정적으로 상태 관리가 되기 시작하더군요. 코드가 깔끔해지니 신규 기능을 요청해도 버그가 확 줄고, 개발 속도가 붙었습니다. 완전한 '바이브 코딩'은 아니고, 3~4일 정도는 AI가 짠 코드를 제가 꼼꼼히 리뷰하고 수정하는 과정을 거쳤습니다. 프로젝트가 궤도에 오른 뒤부터는 Spec 문서 없이 생각나는 대로 프롬프팅 해도 찰떡같이 알아듣고 짜주기 시작했습니다. (그래도 아직까지는 중요한 코드들은 제가 직접 리뷰를 진행하면서 AI에게 제가 원하는 방향으로 수정 요청을 합니다.)
UI 개발 과정
디자이너가 없는 1인 개발자의 설움... 이번에는 이렇게 해결했습니다.
- Claude Web (Opus 4.1)을 켜서 요구사항과 원하는 분위기를 설명하고 Artifact(HTML)로 UI를 먼저 뽑습니다.
- HTML 화면을 보면서 계속 핑퐁 하며 디자인을 다듬습니다.
- 최종적으로 마음에 드는 디자인이 나오면, 그 HTML 코드와 스크린샷을 Claude Code에 던져주고 "이거랑 똑같이 Flutter로 짜줘"라고 시킵니다.
이미지만 던져주고 짜달라고 하면 속도도 느리고 디테일이 많이 깨지는데, HTML 코드를 기반으로 변환하라고 하니 훨씬 결과가 좋았습니다. 아직까진 이 방식이 베스트인 것 같습니다.
다국어 지원
예전에는 엑셀에 한땀한땀 넣고 구글 번역기 돌려서 strings.xml에 복붙하던 노가다를 이제 안 해도 됩니다.
그냥 Claude Code에게 "strings.xml 읽어서 이 언어들로 자연스럽게 번역해 줘" 하면 알아서 파일 수정까지 끝내줍니다. 퀄리티도 예전 구글 번역기보다 훨씬 낫습니다. 하지만 여전히 용어 통일이 안 되는 문제가 있어서 프로세스를 좀 개선했습니다.
- 단어 맵핑: 앱의 기능을 설명해주고, 현재 사용된 텍스트를 분석해 '단어 맵핑 파일'을 먼저 만들라고 시킵니다.
- 검수: 맵핑 과정에서 모호한 단어는 마킹하라고 하고, 제가 직접 보거나 다른 LLM과 상의해서 결정합니다.
- 번역: 확정된 맵핑 파일을 기반으로 "직역하지 말고 자연스럽게" 번역하라고 지시합니다.
- 최종 리뷰: 번역된 결과물을 Opus 4.1 같은 고성능 모델에게 던져서 최종 감수를 시킵니다.
Claude Code 사용 팁
마지막으로 몇 달간 굴러보며 얻은 소소한 팁들입니다.
- 권한 허용 스킵: Git으로 소스 관리를 하고 있다면 claude --dangerously-skip-permissions 옵션을 쓰세요. 파일 수정할 때마다 y/n 누르는 거 너무 귀찮고 시간 낭비입니다.
- 알림 설정: 오래 걸리는 작업 시켜놓고 유튜브 보다가 완료된 줄도 모르고 시간 허비하는 경우가 많습니다. Claude Code의 hook에 애플스크립트를 실행하도록 연동해서 작업 끝나면 데스크탑 알림이 오게 설정해 두니 좋습니다.
- Subagent 활용: 다국어 번역처럼 병렬 처리가 필요한 건 Subagent를 만들어서 돌리면 빠릅니다. 컨텍스트도 분리돼서 토큰 절약에도 도움 됩니다.
- Context 관리: 좋은 결과물을 위해 자주
/clear를 해주는 게 정신건강에 좋습니다. - 멀티태스킹: Git worktree를 써서 터미널 여러 개 띄워두고 동시에 여러 기능을 개발할 수도 있습니다. (단, 사람 머리에 과부하가 와서 급격히 피로해질 수 있음 주의...)
확실히 AI 에이전트 덕분에 혼자서 엄두도 못 냈을 작업을 빠르게 쳐낼 수 있었습니다. 개발자 여러분도 한 번 적극적으로 도입해 보시길 추천합니다.
아참 제가 만든 앱 링크를 깜빡 할 뻔 했네요 ㅎㅎ
- Google Play 앱 다운로드: https://play.google.com/store/apps/details?id=com.sunnysidesoft.virtualtablet.bluelink
- 웹사이트: https://www.sunnysidesoft.com/ko/virtualtablet-bluetooth/
댓글 7
이제 안드로이드는 기기 자체가 hid peripheral 로 작동할 수 있나보군요
본문 중간에 ios도 된다고 하셨는데... 맞나요? 애플이 그럴리가 없을 것 같은데......
애플 공식문서상으로는 된다/안된다 명확하게 나와있지 않아서 좀 모호하긴한데요. 일단 앱스토어에 앱이 올라왔다는건 리뷰를 통과했단 뜻이니 저도 한번 만들어보려구요.
해당 앱 방금 설치해서 사용해봤는데 신기하네요.. HID over GATT 란게 있군요,,
맥이랑 연결하는데 별도의 페어링 없이 연결되는게(아마 같은 애플 아이디라서?) 어이없기도 하고.. 신기하기도 하고..
어찌됐건 좋은 기능인것 같아서 Android와 비슷하게 iOS용도 지금 열심히 만들고있습니다! flutter로 만들긴했지만 Android/iOS가 블루투스 연결 flow도 많이 다르고해서 거의 반쯤은 새로 만들어야하는 상황이네요.
말씀하신것 처럼 iOS의 경우 블루투스 연결방식이 독특한데 iOS기기와 Mac이 동일 애플 ID로 로그인 되어있으면 블루투스 추가 페어링 없이도 연결이 가능한 것 같더라고요 (Apple의 Continuity feature를 위해 같은 ID로 로그인된 디바이스들은 암묵적으로 미리 페어링이 되어있는 상태인 것 같습니다.)
관심있으시면 한번 다운받아서 사용해보시고 리뷰도 남겨주시면 감사하겠습니다
https://apps.apple.com/kr/app/virtualtablet-bluetooth/id6758901525
잠깐 써보려다가 놀라고 갑니다.... 대단하시네요 ㄷㄷ
당장은 아닌데, 써볼 일이 있을 것 같아.. 그때 다시 돌아오겠습니다...ㅋㅋㅋㅋㅋ