[작성자:] 컴맹 집사

  • 앱 닫으면 결과가 사라진다고? 이전 결과 보기 만든 이야기

    앱 닫으면 결과가 사라진다고? 이전 결과 보기 만든 이야기

    작성자: 컴맹 집사

    대표 이미지: 저장된 결과가 있으면 첫 화면에 “이전에 받은 작위증 보기” 버튼이 나타난다 (출처: 직접 캡처한 화면(2026년 9월 20일))

    이 글에서 얻는 것

    • 이런 분께 앱을 닫거나 새로고침하면 결과가 사라지는 분
    • 핵심 답 로그인 없이 휴대폰 브라우저에 결과를 저장했다. 완성된 그림 대신 다시 그리는 데 필요한 재료(폐하 정보, 답 7개, 발급일, 줄인 사진)만 저장한다
    • 바로 쓰는 팁 그림 대신 재료를 저장하면 나중에 디자인을 바꿔도 예전 결과가 새 디자인으로 다시 그려진다

    “어제 받은 작위증 다시 보여 주려고 했는데, 처음부터 다시 해야 하네.”

    친구의 말이었다. 전날 받은 작위증을 다른 사람에게 보여 주려고 앱을 다시 열었더니 결과가 남아 있지 않았다. 앱을 닫거나 새로고침만 해도 결과가 사라졌다.

    나는 이게 당연한 줄 알았다. 진단은 한 번 하고 끝나는 거니까. 그런데 작위증을 나중에 다시 보여 주고 싶은 사람에게는 꽤 불편한 일이었다.

    왜 결과가 사라질까

    AI에게 먼저 원인을 물었다.

    지금 앱은 결과를 화면이 열려 있는 동안만 기억합니다. 화면을 닫거나 새로고침하면 앱이 처음부터 다시 시작되기 때문에, 그동안 기억하던 내용이 모두 지워집니다.

    비유하자면 지금 앱은 칠판에 결과를 적어 두는 것과 같았다. 수업이 끝나면(화면을 닫으면) 칠판을 지운다. 결과를 남기려면 공책에 적어야 한다.

    그 공책을 어디에 둘 것인가가 문제였다.

    공책을 둘 수 있는 곳은 두 군데

    AI가 알려 준 선택지는 두 가지였다.

    1. 서버에 저장하기
    결과를 인터넷 저 너머의 서버에 보관한다. 어느 기기에서든 볼 수 있다. 대신 회원가입이나 로그인이 있어야 누구의 결과인지 구분할 수 있고, 서버와 데이터베이스를 준비해야 한다.

    2. 사용자의 휴대폰(브라우저)에 저장하기
    결과를 그 휴대폰의 브라우저 안에 보관한다. 로그인도 서버도 필요 없다. 대신 그 휴대폰, 그 브라우저에서만 볼 수 있다.

    사진 기능 때와 같은 고민이었다. 결론도 같았다. 이 앱에 로그인을 넣을 이유는 없었다. 재미로 하는 집사 진단을 위해 회원가입을 할 사람은 많지 않다. 휴대폰 안에 저장하는 방식으로 정했다. 이 방식에 쓰이는 것이 LocalStorage라는 기능인데, 이야기가 길어서 다음 글에 따로 적었다. (출처: MDN 웹 문서, Window.localStorage) 이 글에서는 무엇을, 어떻게 보여 줄지 기능을 설계한 과정을 다룬다.

    무엇을 저장할지 정하기

    완성된 작위증 그림을 통째로 저장하면 될까? AI의 생각은 달랐다. 그림은 용량이 크고, 나중에 작위증 디자인을 바꾸면 옛날 그림이 그대로 남는다. 대신 작위증을 다시 그리는 데 필요한 재료만 저장하자고 했다.

    저장할 것 이유
    폐하 정보(이름, 성격, 좋아하는·싫어하는 활동, 왕국 분위기, 집사 닉네임) 왕국과 작위증에 들어간다
    질문 7개의 답 집사 유형과 작위를 다시 계산할 수 있다
    발급일 작위증에 적힌 날짜를 그대로 유지한다
    작게 줄인 폐하 사진 작위증 액자에 다시 넣는다

    재료만 있으면 앱이 작위증을 그 자리에서 다시 그린다. 나중에 작위증 디자인을 크게 바꿨을 때도, 예전에 받은 작위증이 새 디자인으로 자연스럽게 다시 그려졌다. 재료를 저장해 둔 덕을 톡톡히 봤다.

    사진은 가장 고민한 부분이다. 사진을 남기면 편하지만 용량이 크다. 그래서 사진 업로드 때 이미 작게 줄여 둔 사진만 저장하게 했다. 그래도 저장 공간이 부족하면 사진만 빼고 나머지를 저장해서, 저장이 실패해도 작위증 기록 자체는 남게 했다. 이 사진도 그 휴대폰 브라우저 안에만 남고, 어디로도 전송되지 않는다.

    하나만 남길까, 여러 개를 남길까

    처음엔 지난 결과를 목록으로 여러 개 남기는 방법도 생각했다. 하지만 이 앱에서 작위증은 “지금 나의 집사 작위”라는 의미가 컸다. 목록을 만들면 화면도, 지우기 기능도, 설명도 늘어난다. 그래서 가장 최근에 받은 작위증 하나만 남기기로 했다. 새로 진단을 받으면 이전 기록은 새 기록으로 바뀐다.

    단순하게 정하고 나니 만들 것도, 설명할 것도 줄었다. 초보자에게는 이게 큰 장점이었다.

    어디서 보게 할까

    첫 화면에 “이전에 받은 작위증 보기” 버튼을 만들었다. 누르면 저장해 둔 재료로 작위증이 다시 그려지고, 거기서 저장과 공유도 그대로 할 수 있다.

    저장된 기록이 있을 때의 홈 화면
    기록이 있으면 아카데미·궁합 보기 같은 이어하기 메뉴도 보인다
    출처: 왕립 개집사협회 앱 2026년 9월 20일 버전 화면, 직접 캡처

    처음에는 저장된 작위증이 있을 때만 이 버튼이 보이게 했다. 그런데 앱을 다시 보다가 생각이 바뀌었다. 처음 온 사람에게는 첫 화면에 볼거리가 너무 적었다. 그래서 버튼을 항상 보이게 하고, 작위증이 아직 없으면 버튼 글자를 “아직 작위가 없어요 · 지금 받기”로 바꿔서 누르면 바로 진단이 시작되게 했다. 같은 자리의 버튼이 상황에 따라 다른 일을 하게 만든 것이다.

    진단을 마치면 폐하 정보, 답 7개, 발급일, 줄인 사진을
    이 휴대폰 브라우저에 저장해 줘. 가장 최근 것 하나만.
    저장 공간이 부족하면 사진만 빼고 저장해 줘.
    첫 화면에 "이전에 받은 작위증 보기" 버튼을 항상 보여 주고,
    저장된 게 없으면 "아직 작위가 없어요 · 지금 받기"로 바꿔서 진단을 시작하게 해 줘.
    

    테스트하며 발견한 것

    • 새로고침 후에도 작위증이 남는가 → 남는다.
    • 앱을 닫았다 다시 열어도 남는가 → 남는다.
    • 다른 휴대폰에서는 보이는가 → 안 보인다. (의도한 대로)
    • 같은 휴대폰이라도 다른 브라우저에서는 보이는가 → 안 보인다.
    • 저장 기능이 막힌 환경(일부 비공개 모드 등)에서도 앱이 멈추지 않는가 → 저장만 안 되고 앱은 그대로 쓸 수 있다.

    네 번째 항목이 뜻밖이었다. 카카오톡에서 링크를 열어 진단한 뒤 나중에 크롬으로 열면 작위증이 없다. 카카오톡 안의 브라우저와 크롬은 서로 다른 공책을 쓰기 때문이다. 기술적으로 어쩔 수 없는 부분이라, 이용안내에 “작위증은 이 브라우저에만 저장된다”는 설명을 넣었다.


    이전 글: 카톡으로 자랑하고 싶게! 웹앱 공유 버튼 만드는 법
    다음 글: LocalStorage, 브라우저 속 작은 공책? 컴맹도 이해한 저장의 원리

  • 카톡으로 자랑하고 싶게! 웹앱 공유 버튼 만드는 법

    카톡으로 자랑하고 싶게! 웹앱 공유 버튼 만드는 법

    작성자: 컴맹 집사

    대표 이미지: 결과 화면 아래에 공유하기 버튼을 두었다 (출처: 왕립 개집사협회 앱 2026년 9월 19일 버전 화면, 직접 캡처)

    이 글에서 얻는 것

    • 이런 분께 웹앱에 카톡 등으로 보내는 공유 버튼을 달고 싶은 분
    • 핵심 답 Web Share API로 휴대폰 기본 공유 창을 빌려 쓴다. 공유 창이 안 뜨는 환경에서는 링크를 복사하고 안내를 띄운다
    • 바로 쓰는 팁 어떤 환경에서든 버튼이 뭔가는 하게 만들자. 아무 반응 없는 버튼이 가장 답답하다

    테스트 앱은 공유로 살아난다. 누군가 결과를 단체방에 올리고, 그걸 본 사람이 “나도 해 볼래”라며 링크를 누른다. 이 흐름이 없으면 앱은 내 친구 몇 명 안에서 끝난다.

    그동안 사람들은 결과를 공유하려고 캡처하고, 카카오톡을 열고, 방을 고르고, 사진을 붙이고, 링크를 따로 복사해서 붙여야 했다. 다섯 단계를 버튼 하나로 줄이는 게 이번 목표였다.

    공유 방법은 여러 가지였다

    AI에게 “웹앱에서 결과를 공유하는 방법을 초보자가 만들기 쉬운 순서대로 알려 줘”라고 물었다.

    방법 설명 난이도
    링크 복사 버튼을 누르면 앱 주소가 복사된다 쉬움
    휴대폰 기본 공유 메뉴 휴대폰의 공유 창(카톡, 문자, 인스타 등)이 뜬다 쉬움
    카카오톡 전용 공유 카톡 공유 카드가 예쁘게 만들어진다 어려움
    SNS별 공유 버튼 페이스북, X 등 각각의 버튼 보통

    휴대폰 기본 공유 메뉴라는 게 눈에 들어왔다. 사진이나 기사를 공유할 때 아래에서 올라오는 그 창이다. 웹앱에서도 그 창을 불러올 수 있다면, 카카오톡이든 문자든 사용자가 알아서 고르면 된다.

    Web Share API: 휴대폰의 공유 창 빌려 쓰기

    이 기능의 이름은 Web Share API였다. (출처: MDN 웹 문서, Web Share API) API라는 말이 처음엔 어려웠는데, AI는 이렇게 설명했다.

    API는 “이렇게 부탁하면 이렇게 해 줄게”라고 정해 둔 창구입니다. Web Share API는 웹앱이 휴대폰에게 “공유 창 좀 띄워 줘”라고 부탁하는 창구예요.

    식당에서 주방에 직접 들어가지 않고 주문 창구로 주문하는 것과 비슷하다. 공유 창을 내가 만들 필요 없이, 휴대폰에 부탁만 하면 된다.

    결과 화면에 "공유하기" 버튼을 만들어 줘.
    누르면 휴대폰 기본 공유 창이 뜨게 해 줘.
    공유 내용:
    - 문구: "초코 폐하의 발바닥 궁정대신 작위를 받았어요! #왕립개집사협회"
    - 다음 줄에 앱 주소
    폐하 이름과 작위는 결과에 맞게 바뀌게 해 줘.
    

    휴대폰에서 버튼을 누르자 익숙한 공유 창이 올라왔다. 카카오톡을 고르니 문구와 링크가 함께 들어간 메시지가 준비돼 있었다. 다섯 단계가 두 번의 터치로 줄었다.

    공유 창이 안 뜨는 환경

    기쁨도 잠시, 컴퓨터로 앱을 연 친구가 “공유 버튼 눌러도 아무것도 안 되는데?”라고 했다. Web Share API는 모든 환경에서 지원되지 않는다. 일부 컴퓨터 브라우저와 오래된 휴대폰에서는 동작하지 않았다.

    그래서 조건문을 한 번 더 썼다.

    • 만약 공유 창을 띄울 수 있는 환경이면 → 공유 창을 띄운다.
    • 그렇지 않으면 → 앱 주소를 복사하고 “링크가 복사되었어요”라는 안내를 잠깐 보여 준다.

    이렇게 하면 어떤 환경에서든 버튼이 뭔가는 해 준다. 아무 반응 없는 버튼이 가장 답답하다는 건 이미지 저장 기능에서 이미 배웠다.

    이미지도 같이 보낼 수 있을까

    다음 욕심은 작위증 이미지까지 함께 공유하는 것이었다. AI에게 물으니 Web Share API로 파일도 공유할 수 있지만, 지원하는 기기와 브라우저가 링크 공유보다 적다고 했다. 실제로 해 보니 내 안드로이드 휴대폰에서는 이미지와 문구가 함께 카카오톡으로 넘어갔지만, 일부 환경에서는 이미지만 가거나 아예 동작하지 않았다.

    공유받은 작위증 이미지
    친구에게 공유된 작위증 이미지
    출처: 직접 캡처한 화면(2026년 9월 20일)

    그래서 역할을 나눴다.

    • 작위증 공유: 작위증 이미지와 문구를 함께 보낸다. 안 되는 환경에서는 “이 브라우저는 바로 공유를 지원하지 않아요. 이미지로 저장한 뒤 공유해 주세요”라고 안내한다.
    • 앱 링크 보내기: 작위증이 없어도 누를 수 있는 버튼으로, 앱 주소와 소개 문구만 보낸다. 거의 모든 환경에서 동작한다.

    한 버튼에 모든 걸 담으려다 불안정해지는 것보다 역할을 나누는 편이 안정적이었다.

    카카오톡 전용 공유를 미룬 이유

    한국에서는 카카오톡 공유가 가장 중요하다. 전용 공유를 쓰면 제목, 이미지, 버튼이 들어간 카드가 만들어진다. 욕심이 났지만 일단 미뤘다.

    • 카카오 개발자 사이트에 가입하고 앱을 등록해야 한다.
    • 앱 키를 발급받아 코드에 넣어야 한다.
    • 등록한 도메인(앱 주소)이 맞아야 동작한다.

    하나하나는 할 수 있는 일이었지만, 초보자인 나에게는 새 개념이 너무 많았다. 휴대폰 기본 공유 창으로도 카카오톡 공유는 충분히 됐다. 카카오톡 전용 공유는 앱이 자리 잡은 뒤 다시 도전하기로 “나중에 할 것” 목록에 적었다.

    공유 문구를 다듬은 과정

    의외로 시간이 걸린 건 문구였다. 처음엔 “집사 작위 진단 결과를 공유합니다”였는데, 아무도 누르고 싶지 않은 문장이었다.

    몇 번 고친 끝에 원칙을 정했다.

    • 결과를 먼저 말한다: “초코 폐하의 발바닥 궁정대신 작위를 받았어요!”
    • 상대를 끌어들인다: “우리 집 강아지가 왕이라면, 나는 어떤 집사일까?”
    • 해시태그는 하나만: #왕립개집사협회
    • 짧게: 카톡 미리보기에서 잘리지 않을 길이

    친구들 반응을 보면, 결과를 먼저 말하는 문구를 받은 사람이 링크를 더 많이 눌렀다. 남의 결과를 보면 내가 어떤 집사일지 궁금해지기 때문이다.

    공유 후 돌아오는 사람을 위한 준비

    공유 기능을 만들고 나서야 깨달은 게 있다. 링크를 받은 사람이 들어왔을 때 첫 화면이 중요하다는 점이다. 친구의 결과 문구를 보고 들어왔는데 첫 화면이 밋밋하면 바로 나간다. 앞에서 첫 화면을 다듬어 둔 게 여기서 빛을 봤다. 공유 문구의 분위기(“작위를 받았어요!”)와 첫 화면의 분위기(“나도 왕실 집사 되기”)가 이어지도록 맞춘 것도 도움이 됐다.

    카카오톡 안에서 열었을 때

    링크를 카카오톡으로 받으면 대부분 카카오톡 안의 브라우저에서 열린다. 이 안에서는 저장이나 공유가 제대로 안 되는 경우가 있었다. 그래서 카카오톡, 인스타그램 같은 앱 안에서 열린 경우를 알아채서 “다른 브라우저로 열기” 안내와 “주소 복사” 버튼을 보여 주게 했다. 카카오톡에서는 기본 브라우저로 바로 여는 버튼도 넣었다. 다만 이 부분은 기기마다 동작이 달라서 여러 휴대폰에서 계속 확인하고 있다.


    이전 글: 결과 이미지 저장, 아이폰만 안 되던 미스터리 해결기
    다음 글: 앱 닫으면 결과가 사라진다고? 이전 결과 보기 만든 이야기

  • 결과 이미지 저장, 아이폰만 안 되던 미스터리 해결기

    결과 이미지 저장, 아이폰만 안 되던 미스터리 해결기

    작성자: 컴맹 집사

    대표 이미지: 작위증을 이미지로 저장하는 버튼(영어판 화면) (출처: 직접 캡처한 화면(2026년 9월))

    이 글에서 얻는 것

    • 이런 분께 결과 이미지 저장 기능이 아이폰에서만 안 되는 분
    • 핵심 답 아이폰 사파리와 카카오톡 같은 앱 속 브라우저는 다운로드가 막히는 경우가 많다. 그런 환경에서는 이미지를 크게 띄우고 “길게 눌러 저장하세요”라고 안내했다
    • 바로 쓰는 팁 가진 기기가 적다면 친구에게 “버튼 한 번 눌러 보고 결과 캡처 보내 줘”라고 부탁하는 게 가장 확실한 테스트였다

    “캡처하면 위에 시계랑 배터리까지 찍혀.”
    “작은 폰이라 증서가 한 화면에 안 들어와서 두 번 찍었어.”

    작위증을 만든 뒤 들어온 불만이었다. 다들 결과를 캡처해서 공유하고 있었는데, 캡처는 생각보다 불편했다. 증서만 깔끔하게 담긴 이미지를 버튼 하나로 저장할 수 있으면 좋겠다는 요청이 이어졌다.

    화면을 그림으로 바꾼다는 것

    AI에게 “작위증 부분만 이미지 파일로 저장하는 버튼을 만들 수 있어?”라고 물었다. 가능하다고 했고, 원리는 이렇게 설명해 줬다.

    • 웹 화면은 글자와 모양을 적어 둔 설명서다. “여기에 금색 테두리, 여기에 이 글자”라는 식이다.
    • 이 설명서를 그대로 사진 찍듯 저장하는 기능은 브라우저에 없다.
    • 대신 캔버스(canvas)라는 도화지에 그린 그림은 버튼 하나로 PNG 파일로 내보낼 수 있다. (출처: MDN 웹 문서, HTMLCanvasElement.toBlob)

    외부 도구(라이브러리)로 화면을 그림으로 바꾸는 방법도 있다고 했다. 하지만 작위증을 처음부터 캔버스에 그리도록 만들어 둔 덕분에 그럴 필요가 없었다. 이미 도화지에 그려진 작위증을 파일로 내보내기만 하면 됐다.

    첫 시도: 저장은 되는데 흐릿하다

    AI가 만들어 준 “작위증 저장하기” 버튼을 누르자 파일이 내려받아졌다. 그런데 이미지를 열어 보니 글자가 뿌옇게 번져 있었다.

    원인은 해상도였다. 요즘 휴대폰은 같은 크기 안에 픽셀을 2~3배 촘촘하게 담는다. 그런데 도화지를 화면에 보이는 크기 그대로 작게 만들어 두었으니, 확대해 보면 흐릿할 수밖에 없었다.

    해결은 도화지 자체를 크게 만드는 것이었다. 작위증 도화지를 가로 1,000픽셀이 넘는 크기로 만들고, 화면에서만 줄여서 보여 주게 했다. 파일 크기는 조금 커졌지만 글자가 선명해졌다.

    두 번째 문제: 글꼴이 바뀌어 저장된다

    선명해진 이미지에서는 제목 글꼴이 기본 글꼴로 바뀌어 있을 때가 있었다. 화면에서는 멋진 명조체인데 저장된 그림에서는 평범한 글꼴이었다.

    글꼴 파일을 불러오는 데 잠깐 시간이 걸리는데, 불러오기가 끝나기 전에 글자를 그려서 생긴 문제였다. AI는 “글꼴 불러오기가 끝난 걸 확인한 뒤 그리게” 바꿔 줬다. 저장 버튼을 누르면 아주 잠깐 기다렸다가 그림을 그린다. 사용자는 거의 느끼지 못할 정도다.

    세 번째 문제: 아이폰에서는 반응이 없다

    안드로이드 휴대폰에서는 버튼을 누르면 다운로드 알림이 뜨고 갤러리에 저장됐다. 그런데 아이폰을 쓰는 친구가 말했다. “눌러도 아무 반응이 없는데?”

    이 문제가 가장 오래 걸렸다. 몇 번 주고받으며 알게 된 건, 아이폰의 사파리 브라우저는 웹에서 파일을 내려받는 방식이 안드로이드와 다르다는 것이다. 특히 카카오톡 같은 앱 안에서 링크를 열면(인앱 브라우저) 다운로드가 막히는 경우가 많았다.

    그래서 방법을 두 갈래로 나눴다.

    • 다운로드가 되는 환경: 바로 파일로 저장한다.
    • 다운로드가 어려운 환경: 만든 이미지를 화면에 크게 띄우고, “이미지를 길게 눌러 저장하세요”라는 안내를 보여 준다.

    아이폰 사용자는 이미지를 길게 누르면 나오는 “사진 앱에 저장” 메뉴에 익숙했다. 이 방식으로 바꾸자 “반응이 없다”는 말이 더 나오지 않았다.

    나중에 공유 기능을 만들면서 알게 된 것인데, 일부 휴대폰에서는 공유 메뉴로 이미지를 저장하는 방법도 있었다. 이건 다음 글에서 다룬다.

    저장되는 이미지 다듬기

    이미지로 저장과 스토리용 세로 저장 버튼
    나중에 추가한 스토리용 세로 저장 버튼
    출처: 왕립 개집사협회 앱 2026년 9월 28일 버전 화면, 직접 캡처
    • 버튼은 저절로 빠진다: 도화지에는 증서만 그리니, 아래의 “다시 하기”, “저장하기” 버튼이 그림에 찍히지 않는다. 캔버스로 만든 덕을 한 번 더 본 셈이다.
    • 앱 주소 넣기: 증서 맨 아래에 작은 글씨로 앱 주소를 넣었다. 이미지만 공유돼도 보는 사람이 앱을 찾아올 수 있다. 주소는 지금 접속한 주소를 자동으로 읽어 적게 해 두어서, 도메인이 바뀌어도 고칠 필요가 없다.
    • 파일 이름: 작위증.png보다 RKBA-작위증-초코.png처럼 폐하 이름이 들어가게 했다. 여러 폐하의 작위증을 저장해도 구분이 된다.

    사진이 있을 때도 잘 저장될까

    걱정했던 부분이 하나 있었다. 사용자가 올린 강아지 사진과 배경 그림도 도화지 안에 잘 들어갈까? 외부 사이트의 이미지는 보안 규칙 때문에 그림으로 옮기지 못하는 경우가 있다고 들었기 때문이다.

    다행히 내 앱의 사진은 사용자 휴대폰 안에서 불러온 것이라 문제가 없었다. 기본 이미지도 내 앱 폴더 안에 있는 파일이라 괜찮았다. 사진을 서버에 올리지 않기로 한 결정이 여기서도 일을 줄여 줬다.

    저장 기능 테스트 체크리스트

    • 안드로이드 크롬에서 버튼 → 갤러리에 저장되는가
    • 아이폰 사파리에서 버튼 → 이미지가 뜨고 길게 눌러 저장되는가
    • 카카오톡 안에서 링크를 열었을 때도 안내가 제대로 나오는가
    • 사진을 넣은 경우와 안 넣은 경우 모두 이미지가 온전한가
    • 이름이 긴 폐하도 증서 모양이 깨지지 않는가
    • 저장된 이미지의 글자가 휴대폰에서 확대해도 선명한가

    모든 기기를 가지고 있지 않아서 친구들에게 부탁했다. “이 버튼 한 번만 눌러 보고 결과 캡처 보내 줘.” 가장 확실한 테스트 방법이었다.

    한 가지는 아직 숙제로 남아 있다. 한 번은 저장한 파일을 열려고 하자 “저장할 수 없는 파일 형식”이라는 오류가 났다. 어떤 기기와 브라우저에서, 어떤 순서로 눌렀는지 기록해 두지 않아서 다시 재현하지 못했다. 오류가 나면 언제, 어디서, 무엇을 하다가 났는지 적어 두어야 고칠 수 있다는 걸 이때 배웠다. 지금은 기록해 두고 다음에 고치기로 했다.

    저장은 해결됐다. 하지만 사람들이 정말 원하는 건 저장이 아니라 보내기였다. 다음 글에서는 공유 버튼을 만든 과정을 적었다.


    이전 글: 사진 안 넣으면 빈 액자? 기본 이미지로 빈자리 없애는 법
    다음 글: 카톡으로 자랑하고 싶게! 웹앱 공유 버튼 만드는 법

  • 사진 안 넣으면 빈 액자? 기본 이미지로 빈자리 없애는 법

    사진 안 넣으면 빈 액자? 기본 이미지로 빈자리 없애는 법

    작성자: 컴맹 집사

    대표 이미지: 사진이 없을 때 처음에는 발바닥 문양만 보였다 (출처: 앱에서 발급한 작위증, 직접 저장)

    이 글에서 얻는 것

    • 이런 분께 사진이나 값이 비었을 때 화면이 이상하게 나오는 분
    • 핵심 답 사진이 없으면 기본 이미지를, 그마저 못 불러오면 왕관 이모지를 보여 주도록 두 겹으로 대비했다
    • 바로 쓰는 팁 새 화면마다 “이 칸이 비면 무엇이 보이나, 불러오다 실패하면 어떻게 되나, 기본값도 분위기에 맞나” 세 가지를 물어보자

    사진 업로드 기능을 배포하고 며칠 뒤, 친구가 작위증 캡처를 보내왔다. 한가운데 동그란 액자가 텅 비어 있었다. 사진을 넣지 않고 발급받은 것이다.

    빈 액자는 생각보다 허전했다. “여기 뭔가 빠졌어요”라고 말하는 것 같았다. 사진은 선택 사항이라 모두가 넣지는 않는다. 사진이 없어도 작위증이 완성돼 보여야 했다.

    사진이 없는 경우는 생각보다 많았다

    사진이 비는 상황을 정리해 보니 한두 가지가 아니었다.

    • 사용자가 일부러 사진을 안 넣은 경우
    • 휴대폰에 마땅한 사진이 없는 경우
    • 사진을 골랐는데 불러오기에 실패한 경우
    • 저장 공간이 부족해서 사진만 빠지고 저장된 경우

    어느 경우든 빈 액자 대신 기본 이미지가 보이게 하기로 했다.

    기본 이미지로 무엇을 쓸까

    처음 계획은 이미지 생성 AI로 “왕관을 쓴 강아지의 왕실 초상화”를 만드는 것이었다. 세계관에 잘 맞고, 실제 사진처럼 저작권 걱정도 덜할 것 같았다.

    사진이 없을 때 대신 쓰는 기본 강아지 사진
    사진이 없을 때 대신 보여 주도록 넣은 기본 이미지
    출처: 앱에 넣은 기본 이미지 파일

    그런데 고민 끝에 방향을 바꿨다. 실제 강아지 사진을 기본 이미지로 쓰기로 한 것이다. 하얀 푸들이 초록색 하네스를 하고 정면을 바라보는 사진이었다. AI가 그린 그림은 예쁘지만 어딘가 비슷비슷해 보였고, 반려인을 위한 앱이라면 실제 강아지의 표정이 주는 따뜻함이 더 어울린다고 생각했다. AI는 원래 기획과 다르다는 점을 짚어 줬지만, 최종 선택은 내가 했다. 왕관이 없어도 충분히 “우리 집 왕”처럼 보였다.

    이 사진은 두 곳에서 쓴다.

    • 작위증: 사진을 넣지 않았을 때 동그란 액자에 들어간다.
    • 첫 화면의 “우리 집 왕”: 사용자가 자기 강아지 사진을 올리기 전까지 기본 사진을 보여 준다. 이 사진은 작위증 사진과 따로 저장되게 했다.

    동그란 액자에 맞게 자르기

    기본 사진을 넣고 나니 새 문제가 보였다. 사진은 네모인데 액자는 동그라미다. 정사각형으로 잘라 동그랗게 보여 주니 머리 위 여백이 너무 많았다. 강아지가 액자 아래쪽에 쏠려 보였다.

    위쪽 경계를 머리에 더 가깝게 당겨서 다시 잘랐다. 이때 쓴 방법이 유용했다. 매번 앱을 고쳐서 배포해 보는 대신, AI에게 동그란 틀을 씌운 미리 보기 그림을 여러 장 만들어 달라고 했다. 마음에 드는 것을 고른 뒤 한 번만 앱에 반영했다. 덕분에 헛배포를 여러 번 줄일 수 있었다.

    조건문으로 사진과 기본 이미지 고르기

    규칙은 앞에서 배운 조건문 그대로다.

    • 만약 사용자가 고른 사진이 있으면 → 그 사진을 액자에 넣는다.
    • 그렇지 않으면 → 기본 사진을 액자에 넣는다.
    작위증의 사진 액자에, 사용자가 사진을 넣지 않았으면
    기본 이미지(assets/default-royal-dog.jpg)를 넣어 줘.
    강아지 얼굴이 액자 가운데 오도록 잘라서.
    사용자가 사진을 넣으면 기본 이미지 대신 그 사진으로 바뀌게.
    

    이미지가 깨졌을 때를 위한 안전장치

    이미지 파일을 못 불러오는 경우도 있다. 파일 이름을 잘못 적었거나, 인터넷이 잠깐 끊겼거나, 파일이 아직 올라가지 않은 경우다. 그러면 액자 안에 깨진 그림 아이콘이 나온다.

    AI가 알려 준 방법은 두 겹이었다.

    1. 이미지에 불러오기 실패 시 실행할 동작(onerror)을 둔다. (출처: MDN 웹 문서, img 요소)
    2. 첫 화면 사진 액자 아래에는 왕관 이모지(👑)를 깔아 두고, 그 위에 사진을 올린다. 사진을 못 불러오면 사진만 숨기면 되고, 아래 왕관이 자연스럽게 드러난다. 깨진 아이콘이 보일 틈이 없다.

    이 안전장치 덕을 실제로 봤다. 기본 사진 파일을 준비하기 전에 기능을 먼저 배포했는데, 그동안 사람들은 깨진 아이콘 대신 왕관을 봤다. 나중에 영어판에서 기본 사진 파일이 빠져 있었을 때도 이 덕분에 화면이 망가지지 않았다.

    작위증 배경 그림도 같은 원칙으로 만들었다. 배경 그림을 못 불러오면 코드로 그린 리본과 인장이 대신 나온다.

    파일 이름과 폴더 정리

    첫 배포 날 대문자 파일 이름 때문에 그림이 깨졌던 경험이 있어서, 이번에는 처음부터 영어 소문자와 하이픈만 썼다. 이미지는 assets 폴더에 따로 모았다.

    kba-butler-app/
    ├─ index.html
    └─ assets/
       ├─ default-royal-dog.jpg   (기본 강아지 사진)
       ├─ cert-bg.jpg             (작위증 배경)
       └─ home-bg.jpg             (첫 화면 배경)
    

    내 앱에도 써먹는 “빈자리” 점검 3가지

    이번 일을 겪고 나서, 새 화면을 만들 때마다 스스로 묻는 질문이 생겼다. 사진뿐 아니라 이름, 점수, 기록처럼 “비어 있을 수 있는 칸”이 있는 앱이라면 누구에게나 쓸모 있는 질문이다.

    1. 이 칸이 비면 화면에 뭐가 보이나? 텅 빈 네모, “undefined” 같은 이상한 글자가 보인다면 대신 보여 줄 기본값이 필요하다.
    2. 불러오다 실패하면 어떻게 되나? 인터넷이 끊기거나 파일이 빠져도 화면 전체가 무너지지 않게, 한 단계 더 아래의 대비책을 둔다. 우리 앱의 “사진 → 기본 사진 → 왕관 이모지”처럼.
    3. 기본값도 세계관에 맞나? 회색 사람 아이콘 하나만 띄우면 앱의 분위기가 깨진다. 우리 앱에서는 기본값도 “우리 집 왕”처럼 보이게 하는 데 신경 썼다.

    AI에게 부탁할 때는 이렇게 말하면 된다. “사진이 없거나 불러오지 못하면 기본 강아지 사진을 보여 줘. 그것마저 실패하면 왕관 그림을 보여 줘.” 단계별로 말해 주면 AI가 빈틈없이 만들어 준다.

    이제 작위증이 완성됐다. 다음 과제는 이 작위증을 이미지 파일로 저장하는 기능이었다. 캡처로는 증서 전체가 깔끔하게 담기지 않는다는 불만이 있었기 때문이다.


    이전 글: 강아지 사진 올리기 기능, 서버 없이 안전하게 만든 방법
    다음 글: 결과 이미지 저장, 아이폰만 안 되던 미스터리 해결기

  • 강아지 사진 올리기 기능, 서버 없이 안전하게 만든 방법

    강아지 사진 올리기 기능, 서버 없이 안전하게 만든 방법

    작성자: 컴맹 집사

    대표 이미지: 사진을 고르면 동그란 액자에 바로 미리보기가 나온다 (출처: 왕립 개집사협회 앱 2026년 9월 19일 버전 화면, 직접 캡처)

    이 글에서 얻는 것

    • 이런 분께 웹앱에 사진 올리기 기능을 넣고 싶지만 서버가 부담스러운 분
    • 핵심 답 사진을 서버에 올리지 않고 휴대폰 안에서만 불러와 보여 주는 방식을 골랐다. 서버도, 사진 보관에 따른 개인정보 부담도 없다
    • 바로 쓰는 팁 큰 원본 사진을 넣으니 오래된 휴대폰에서 화면이 멈췄다. 사진은 긴 쪽 900픽셀 정도로 줄여 쓰자

    작위증을 본 친구들이 한결같이 한 말이 있었다. “여기에 우리 애 사진 넣을 수 있어?”

    나도 처음부터 넣고 싶었던 기능이다. 그런데 막상 만들려니 걱정이 앞섰다. 사진을 올리면 그 사진은 어디로 가는 걸까? 서버가 필요한가? 남의 강아지 사진을 내가 보관해도 되나? 이 글은 그 걱정에서 출발해 사진 기능을 완성한 기록이다.

    “업로드”라는 말에 대한 오해

    AI에게 “사진 업로드 기능을 만들고 싶어”라고 하자 두 가지 방식을 물어 왔다.

    • 방식 A: 사진을 서버에 올려서 저장한다. 나중에 다른 기기에서도 볼 수 있다.
    • 방식 B: 사진을 사용자의 휴대폰 안에서만 불러와 화면에 보여 준다. 어디에도 올라가지 않는다.

    나는 “업로드”라고 하면 당연히 A인 줄 알았다. 그런데 A에는 해야 할 일이 많았다.

    • 사진을 저장할 서버와 저장 공간이 필요하다.
    • 사진은 개인정보가 될 수 있다. 강아지 사진이라도 배경에 집 안, 사람 얼굴, 주소가 찍힐 수 있다.
    • 보관하려면 개인정보처리방침에 무엇을 얼마나 보관하는지 적고 관리해야 한다.
    • 저장 공간이 늘면 비용이 생길 수 있다.

    반면 내 앱에 필요한 건 “작위증에 사진을 넣어 보여 주는 것”뿐이었다. 사진을 내가 보관할 이유가 없었다. 그래서 방식 B를 골랐다. 사진은 사용자의 휴대폰 안에서만 쓰이고, 나를 포함해 누구에게도 전송되지 않는다.

    첫 배포 날 친구가 물었던 “사진은 어디에 저장돼?”에 이제 자신 있게 답할 수 있게 됐다. “어디에도 안 올라가. 네 폰 안에서만 쓰여.”

    사진 고르기 버튼 만들기

    웹앱에서 사진을 고르는 기능은 생각보다 간단했다. HTML에는 파일을 고르는 입력칸(input type="file")이 원래 있고, 여기에 이미지 파일만 고르게 설정할 수 있다. (출처: MDN 웹 문서, input type=file)

    휴대폰에서 이 버튼을 누르면 휴대폰이 “사진 보관함 / 사진 찍기 / 파일 선택” 메뉴를 보여 준다. 사진첩 화면을 내가 따로 만들 필요가 없었다. 휴대폰이 이미 만들어 둔 기능을 빌려 쓰는 셈이다.

    다만 기본 파일 선택 버튼은 “파일 선택 – 선택된 파일 없음”처럼 투박하게 보였다. AI에게 기본 버튼은 숨기고 예쁜 버튼을 보여 달라고 했다.

    왕국 만들기 화면에 "폐하의 어진(사진)"을 고르는 칸을 만들어 줘.
    사진은 선택 사항이고, 버튼 이름은 "사진 고르기"로.
    누르면 휴대폰 사진첩이 열리게 하고, 이미지 파일만 고를 수 있게.
    기본 파일 선택 버튼 모양은 보이지 않게 숨겨 줘.
    사진은 서버로 보내지 말고 화면에만 보여 줘.
    

    마지막 줄은 일부러 넣었다. AI가 친절하게 서버 업로드 코드까지 만들어 버리는 일을 막기 위해서다.

    고른 사진을 화면에 보여 주는 원리

    사진을 고르면 바로 옆 작은 동그라미에 미리 보기가 뜨고, 작위증 한가운데 동그란 액자에도 들어가게 했다. 왕실 세계관이라 사진 칸 이름도 임금의 초상화를 뜻하는 “어진”으로 붙였다. 원리를 물어보니 이랬다.

    강아지 사진이 들어간 작위증
    올린 사진이 작위증 가운데 액자에 들어간 모습
    출처: 직접 제작한 작위증(이미지 생성 AI 활용), 앱에서 발급
    • 사용자가 사진을 고르면, 브라우저가 그 사진에 임시 주소를 붙여 준다. (출처: MDN 웹 문서, URL.createObjectURL)
    • 이 주소는 그 휴대폰, 그 화면 안에서만 통하는 주소라서 다른 사람은 열 수 없다.
    • 작위증의 사진 자리에 이 임시 주소를 넣으면 사진이 보인다.

    처음 버전은 새로고침하면 사진이 사라졌다. 임시 주소가 없어지기 때문이다. 이 문제는 나중에 “이전 결과 다시 보기”를 만들면서, 줄인 사진을 그 휴대폰 브라우저 안에만 보관하는 방식으로 해결했다. 이때도 사진이 휴대폰 밖으로 나가지 않는다는 원칙은 지켰다.

    사진이 찌그러지는 문제

    처음 사진을 넣자 강아지가 옆으로 뚱뚱해 보였다. 세로로 찍은 사진을 동그란 정사각형 액자에 억지로 맞추면서 늘어난 것이다.

    AI는 CSS 한 줄로 해결해 줬다. object-fit: cover라는 설정으로, 사진 비율은 그대로 두고 액자에 넘치는 부분을 잘라 낸다. 증명사진을 액자에 넣을 때 가장자리를 가리는 것과 비슷하다.

    그러자 새 문제가 생겼다. 강아지 얼굴이 사진 위쪽에 있으면 잘려서 귀만 보였다. 사진 속 위치를 정하는 설정(object-position)으로 가운데보다 조금 위쪽을 기준으로 잘리게 바꿨다. 대부분의 사진에서 얼굴이 액자 안에 들어왔다. 완벽한 방법은 사용자가 위치를 직접 조정하게 하는 것이지만, 첫 버전에서는 이 정도로 충분했다.

    사진이 너무 클 때

    요즘 휴대폰 사진은 한 장에 몇 MB씩 한다. 큰 사진을 넣으니 오래된 휴대폰에서 화면이 잠깐 멈췄다. 나중에 결과를 이미지로 저장할 때도 느려질 게 뻔했다.

    작위증 액자는 기껏해야 수백 픽셀이면 충분하니, 원본을 그대로 쓸 필요가 없었다. 그래서 사진을 고른 직후 긴 쪽이 900픽셀이 되도록 작게 다시 그려서 쓰도록 바꿨다. 이 과정도 전부 휴대폰 안에서 일어난다.

    테스트하며 확인한 것

    • 아이폰과 안드로이드 모두에서 사진첩이 열리는가
    • 카메라로 바로 찍은 사진도 들어가는가
    • 가로 사진, 세로 사진 모두 자연스러운가
    • 사진을 고른 뒤 다른 사진으로 바꿀 수 있는가
    • 사진 없이도 작위증이 이상하지 않은가

    마지막 항목이 생각보다 중요했다. 사진을 안 넣는 사람도 많았고, 그때 빈 액자가 덩그러니 있으면 허전했다. 이 문제는 다음 글에서 따로 해결했다.

    개인정보에 대해 한 번 더

    사진 기능을 만들면서 AI에게 “이 앱이 사진과 관련해서 사용자에게 알려야 할 게 있을까?”라고 물었다. 서버에 저장하지 않더라도 사용자가 안심할 수 있게 알려 주는 것이 좋다는 답이었다. 그래서 사진 칸 이름 옆에 작은 글씨로 안내를 붙였다.

    폐하의 어진(사진) (선택 · 내 기기 안에서만 처리돼요)

    블로그와 앱의 개인정보처리방침에도 같은 내용을 적을 예정이다.


    이전 글: 테스트 결과를 집사 작위증으로! 받고 싶어지는 결과 화면 만드는 법
    다음 글: 사진 안 넣으면 빈 액자? 기본 이미지로 빈자리 없애는 법

  • 테스트 결과를 집사 작위증으로! 받고 싶어지는 결과 화면 만드는 법

    테스트 결과를 집사 작위증으로! 받고 싶어지는 결과 화면 만드는 법

    작성자: 컴맹 집사

    대표 이미지: 처음 발급하던 작위증. 이름과 작위를 문장 속에 넣었다 (출처: 직접 캡처한 화면(2026년 9월 19일))

    이 글에서 얻는 것

    • 이런 분께 테스트 결과를 받고 싶어지는 화면으로 만들고 싶은 분
    • 핵심 답 작위증은 캔버스(Canvas)라는 도화지 위에 배경·사진·글자를 차례로 그려 만든다. 그래서 그대로 그림 파일로 저장할 수 있다
    • 바로 쓰는 팁 배경 위 글자가 흐리면 AI에게 대비를 재 달라고 하자. 금색 글자는 2:1 정도로 읽기 기준 4.5:1에 못 미쳐 진한 색으로 바꿨다

    “당신의 작위: 왕실 돌봄근위관”

    첫 버전의 결과 화면에는 이 한 줄뿐이었다. 틀린 건 아니었지만 재미가 없었다. 친구들도 결과를 보고 “오” 한마디 하고 끝이었다.

    처음 기획할 때부터 이 앱의 하이라이트는 작위증이었다. 왕립 개집사협회가 집사에게 내리는 임명장 같은 증서, 캡처해서 자랑하고 싶어지는 화면이다. 이 글은 결과 한 줄을 증서로 바꾼 기록이다.

    진짜 증서에는 무엇이 들어갈까

    AI에게 “상장이나 임명장에는 보통 어떤 항목이 들어가?”라고 물었다. 답을 참고해 작위증에 넣을 항목을 정했다.

    • 머리글: 왕립 개집사협회 작위증
    • 폐하의 사진: 동그란 액자 안에
    • 받는 이: 집사 닉네임과 모시는 폐하의 이름
    • 작위: 견국 수습집사부터 왕실 총집사까지 5단계 중 하나
    • 집사 유형과 수여 사유: 유형에 어울리는 한두 줄 문장
    • 발급일: 오늘 날짜
    • 발급인: 왕립 개집사협회장
    • 인장: RKBA라고 새겨진 붉은 도장

    작위와 유형마다 문구 만들기

    증서의 맛을 살리는 건 문구였다. 작위마다 뜻과 별칭을, 집사 유형마다 한 줄 소개와 재치 있는 한마디를 준비했다. AI에게 초안을 받고, 반려인들이 읽으며 웃을 수 있도록 손봤다.

    • 1단계 견국 수습집사: 왕실 집사 업무를 처음 시작한 새내기, “떠오르는 새싹 집사”
    • 4단계 발바닥 궁정대신: 왕실의 주요 업무를 맡은 핵심 참모, “왕의 오른발 집사”
    • 간식 협상형 집사: “앉아 한 번에 간식 하나, 이것이 외교입니다.”
    • 전략적 회피형 집사: “못 들은 게 아니라, 전략적으로 안 들은 것입니다.”

    문구를 쓰면서 원칙을 하나 정했다. 어떤 작위가 나와도 기분이 좋아야 한다. 1단계가 나와도 “떠오르는 새싹”처럼 앞으로가 기대되는 말로 채웠다. 테스트 앱은 결과가 마음에 들어야 공유된다.

    이 문구들도 질문 목록처럼 데이터 파일에 모아 두었다. 문구를 고칠 때 한 곳만 보면 된다.

    이름을 문장 속에 넣기

    “위 집사는”보다 “초코 폐하의 집사”가 훨씬 좋다. 입력받은 폐하 이름과 집사 닉네임을 문장 속에 넣어 달라고 요청했다.

    한국어는 이름 뒤에 붙는 조사(은/는, 이/가)가 받침에 따라 달라서 까다로울 수 있다. 이 앱은 세계관 말투상 이름 뒤에 늘 “폐하”를 붙인다. “초코 폐하의 왕국”, “보리 폐하의 집사”처럼 쓰니 조사 문제를 자연스럽게 피할 수 있었다. 집사 닉네임을 비워 두면 “이름 없는 집사”로 표시되게 했다.

    발급일은 오늘 날짜가 자동으로 들어가야 한다. JavaScript에는 현재 날짜를 알려 주는 기능(Date)이 있어서, AI가 “2026년 9월 22일” 같은 한국식 날짜로 바꿔 표시해 줬다. (출처: MDN 웹 문서, Date)

    화면이 아니라 그림으로 그린 이유

    처음에는 작위증을 일반 화면처럼 글자와 테두리로 꾸몄다. 그런데 이렇게 만들면 이미지로 저장하기가 어려웠다. AI는 캔버스(Canvas)라는 기능을 추천했다. (출처: MDN 웹 문서, Canvas API) 화면 위에 도화지를 깔고, 그 위에 배경, 사진, 글자를 차례로 그려 넣는 방식이다. 다 그린 도화지는 그대로 그림 파일로 저장할 수 있다.

    배경은 이미지 생성 AI로 만들었다

    코드로 그린 테두리만으로는 증서 느낌이 나지 않았다. 그래서 배경 그림을 이미지 생성 AI로 만들었다. 요청할 때 가장 신경 쓴 부분은 이것이다.

    이미지 생성 AI로 만든 작위증 배경
    나중에 이미지 생성 AI로 다시 만든 작위증 배경
    출처: 직접 제작한 앱 그림(이미지 생성 AI 활용)
    왕실 증서 배경 이미지를 만들어 줘.
    - 크림색 양피지, 금색 이중 테두리, 위쪽에 왕관
    - 발바닥·뼈다귀 무늬가 들어간 모서리 장식
    - 붉은 리본과 붉은 밀랍 인장 자리
    - 글자는 넣지 말 것 (이름·작위·날짜는 앱이 따로 적는다)
    

    글자를 그림에 넣지 않은 것이 핵심이었다. 이미지 생성 AI는 한글을 자주 틀리게 그린다. 이름과 작위는 사람마다 다르기도 하다. 그래서 배경만 그림으로 쓰고, 글자는 전부 앱이 코드로 그 위에 적게 했다.

    시안 세 가지를 받아 비교했다. 왕관이 크고 파란 리본이 들어간 안은 가운데 공간이 좁았고, 격식이 너무 강한 안은 앱의 귀엽고 따뜻한 분위기와 맞지 않았다. 크림색 양피지에 붉은 리본과 밀랍 인장이 들어간 안을 골랐다. 작위 이름은 붉은 리본 위에 크림색 글자로, 밀랍 인장 자리에는 RKBA 도장을 그려 넣었다. 배경 그림을 불러오지 못하는 경우에 대비해, 코드로 그린 리본과 인장이 대신 나오게 하는 안전장치도 넣었다.

    글자가 잘 안 보이는 문제

    배경을 바꾸자 새 문제가 보였다. 금색 작위 이름이 크림색 배경 위에서 너무 흐렸다. AI에게 글자와 배경의 대비를 재 달라고 하니, 읽기 편한 기준(4.5:1)에 한참 못 미치는 2:1 정도였다. 금색은 테두리와 장식에만 쓰고, 글자는 진한 색으로 따로 정해 해결했다.

    이후 작위증을 한 번 더 손봤다. 가장 급했던 건 발급인(협회장) 문구가 너무 작아서 안 보인다는 점이었다. 발급인 글자를 거의 두 배로 키우고 위에 구분선을 넣어 서명처럼 보이게 했다. 집사 이름은 더 크고 진하게, 왕국 이름은 한 단계 작게 줄여 중요도가 한눈에 보이도록 순서를 다시 잡았다. 사진 액자에는 훈장 같은 테두리를 둘렀다.

    이때 배운 확인 방법이 있다. 화면을 눈으로만 보면 글자가 겹치는지 정확히 알기 어렵다. 그래서 “이미지로 저장”을 눌러 실제로 저장된 파일을 열어 확인했다. 사람들이 받아 가는 것은 결국 그 파일이기 때문이다.

    친구들 반응

    작위증을 넣은 버전을 배포하자 반응이 달라졌다. 친구들이 결과를 캡처해서 단체방에 올리기 시작했다. 결과 한 줄일 때는 없던 일이었다.

    사진 이야기도 계속 나왔다. 작위증 한가운데 동그란 액자에 우리 폐하 사진이 들어가야 완성이라는 것이다. 원래 계획에 있던 기능이지만, 사용자 입에서 먼저 나오니 우선순위가 분명해졌다.

    증서 문구에서 조심한 점

    재미로 만든 증서라도 진짜 공문서처럼 오해받지 않도록 조심했다. 실제 기관 이름이나 공식 도장처럼 보이는 표현은 쓰지 않았고, 발급 주체도 세계관 속 단체인 “왕립 개집사협회”로 했다. 앱에는 “본 콘텐츠는 재미를 위한 오락용이며, 실제 반려동물 양육 능력이나 건강 상태를 평가하지 않는다”는 안내를 넣었다.

    다음 글에서는 친구들이 가장 원했던 기능, 강아지 사진 업로드를 만든 이야기를 적었다.


    이전 글: 조건문, “만약에” 한 마디면 끝! 앱이 알아서 결과를 고르는 원리
    다음 글: 강아지 사진 올리기 기능, 서버 없이 안전하게 만든 방법

  • 조건문, “만약에” 한 마디면 끝! 앱이 알아서 결과를 고르는 원리

    조건문, “만약에” 한 마디면 끝! 앱이 알아서 결과를 고르는 원리

    작성자: 컴맹 집사

    대표 이미지: 조건문은 갈림길에서 길을 고르는 규칙과 같다 (사진: took_a_snap / Pixabay)

    이 글에서 얻는 것

    • 이런 분께 앱이 점수로 결과를 고르는 원리가 궁금한 분
    • 핵심 답 조건문은 “만약에”다. 일곱 유형을 하나씩 견줘 “더 크면 1등을 바꾸는” 키 재기 방식이면 결과가 빌 일이 없다
    • 바로 쓰는 팁 동점일 때는 무작위 대신 우선순위를 정해 두자. 같은 답에는 같은 결과가 나와야 믿음이 간다

    심리 테스트를 끝까지 풀면 마지막에 “당신은 ○○형!”이 뜬다. 앱은 대체 어떻게 내 결과를 골라낼까? 처음엔 엄청 복잡한 계산이 숨어 있을 줄 알았다. 막상 들여다보니 비밀은 우리가 매일 쓰는 말 한 마디였다. 바로 “만약에”다.

    앞 글에서 질문 7개에 답하면 일곱 가지 집사 유형에 점수가 쌓이도록 만들었다. 이번 글은 그 점수를 보고 “이 집사는 무슨 유형인가”를 정하는 이야기다. 코드를 한 줄도 몰라도 읽을 수 있게 썼다.

    앱은 “만약에”로 생각한다

    AI에게 이 원리를 쉽게 설명해 달라고 했더니 이런 예를 들어 줬다.

    만약 비가 오면 우산을 챙긴다. 그렇지 않으면 선글라스를 챙긴다.

    이게 전부다. 상황을 확인하고, 그 결과에 따라 할 일을 고르는 것. 프로그래밍에서는 이걸 조건문이라고 부르고, 코드에는 “만약”이라는 뜻의 영어 단어 if로 적는다. “그렇지 않으면”은 else다. 이 두 단어만 알아도 코드 속 문장이 반쯤은 읽힌다.

    강아지 집으로 바꾸면 더 쉽다. “만약 폐하가 산책줄을 보고 꼬리를 흔들면 산책을 나간다. 그렇지 않으면 간식으로 기분을 살핀다.” 집사라면 하루에도 수십 번 하는 판단이다. 앱도 똑같이 판단할 뿐이다.

    우리 앱에 숨어 있던 “만약에” 세 가지

    왕립 개집사협회 앱을 다시 보니, 앱이 똑똑해 보이던 순간은 거의 다 조건문 덕분이었다.

    • 만약 폐하 이름칸이 비어 있으면 → “폐하의 이름을 입력해 주세요.”를 보여 준다.
    • 만약 지금이 일곱 번째 질문이면 → 결과 화면으로 간다. 아니면 → 다음 질문을 보여 준다.
    • 만약 사진이 있으면 → 사진을 보여 준다. 아니면 → 기본 그림을 보여 준다.

    이렇게 말로 풀고 나니 “코드”라는 단어가 덜 무서워졌다.

    1등 유형 고르기, 첫 시도는 실패였다

    문제는 결과를 고르는 부분이었다. 처음 AI가 만든 방식을 말로 옮기면 이랬다.

    만약 충성형 점수가 4점 이상이면 충성형. 아니고 만약 간식 협상형 점수가 4점 이상이면 간식 협상형…

    그럴듯해 보였다. 그런데 직접 해 보니 구멍이 있었다. 질문 일곱 개에 골고루 답하면 어느 유형도 4점을 넘지 못하는 경우가 많았다. 최고점이 2~3점에 그친 것이다. 그러면 어떤 “만약에”에도 걸리지 않아서, 결과 화면에 작위가 텅 빈 채로 나왔다. 작위 없는 작위증이라니, 폐하가 보셨으면 크게 노하셨을 일이다.

    조건에 따라 나뉜 집사 유형 결과
    가장 높은 점수의 유형이 결과로 나온다
    출처: 왕립 개집사협회 앱 2026년 9월 19일 버전 화면, 직접 캡처

    키 재기 방식으로 바꾸니 해결됐다

    AI에게 “4점 넘는 유형이 없으면 결과가 비어 버린다”고 설명하자 방법을 바꿔 줬다. 정해진 점수를 넘는지 보는 대신, 일곱 유형을 서로 견줘서 가장 큰 것을 고르는 방식이다.

    1. 첫 번째 유형을 일단 “지금까지 1등”으로 세운다.
    2. 두 번째 유형과 비교한다. 만약 더 크면 1등을 바꾼다.
    3. 세 번째, 네 번째… 일곱 번째까지 똑같이 비교한다.
    4. 끝까지 살아남은 1등이 결과다.

    반 아이들을 한 줄로 세워 놓고 “지금까지 제일 큰 아이”를 한 명씩 바꿔 가며 키를 재는 것과 같다. 이 방식이면 점수가 낮아도 누군가는 반드시 1등이 된다. 결과가 빌 일이 없다. 여기서도 핵심은 “만약 더 크면”이라는 조건문 하나였다. (출처: MDN 웹 문서, 비교 연산자)

    점수가 같으면? 폐하도 고민할 문제

    다음 고민은 동점이었다. 충성형 3점, 간식 협상형 3점처럼 두 유형이 나란히 1등이면 누구를 줘야 할까? AI가 세 가지 방법을 내놓았다.

    방법 좋은 점 아쉬운 점
    먼저 나온 유형을 준다 간단하다 코드 순서에 따라 우연히 정해진다
    무작위로 고른다 골고루 나온다 같은 답을 해도 결과가 바뀐다
    우선순위를 미리 정해 둔다 결과가 늘 같고 의도가 분명하다 순서를 직접 정해야 한다

    무작위는 바로 탈락했다. 같은 답으로 두 번 했는데 결과가 다르면 누구라도 “이거 그냥 뽑기네” 하고 실망할 테니까. 테스트 앱은 같은 답이면 같은 결과가 나와야 믿음이 간다.

    그래서 우선순위를 정했다. 무조건 충성형 → 간식 협상형 → 산책 원정대장 → 과잉보호형 → 왕실 기록형 → 평화 유지 전문관 → 전략적 회피형 순서다. 많은 반려인이 “내 얘기네!” 할 만한 유형을 앞에 두었다. 가장 높은 5단계 작위로 이어지는 평화 유지 전문관은 너무 쉽게 나오지 않도록 뒤로 보냈다.

    AI에게는 이렇게만 말했다.

    점수가 같은 유형이 여러 개면, 아래 순서에서 앞에 있는 유형을 결과로 해 줘. 같은 답이면 항상 같은 결과가 나와야 해.

    규칙을 말로 또박또박 적어 주니, AI가 그대로 조건문으로 옮겨 줬다.

    1만 가지 경우를 AI가 대신 눌러 봤다

    규칙을 만들었으면 진짜 그렇게 되는지 확인해야 한다. 처음엔 손으로 했다. 충성형이 나오게 충성형 보기만 고르고, 회피형이 나오게 회피형 보기만 고르는 식으로 일곱 유형을 하나씩 확인했다. 동점이 나오도록 답을 섞어서도 해 봤다.

    하지만 손가락에는 한계가 있었다. 그래서 AI에게 자동으로 확인하는 테스트를 만들어 달라고 했다. 폐하 정보와 답을 조합할 수 있는 경우를 모두 돌려 보니 1만 가지가 넘었다. 결과가 비는 경우는 없는지, 같은 입력이면 늘 같은 결과가 나오는지를 한 번에 검사했다. 사람이 하나씩 눌렀다면 며칠은 걸렸을 일이다.

    같은 원칙을 왕국 이름과 표어에도 적용했다. 매번 무작위로 뽑으면 같은 사람이 다시 해도 왕국 이름이 바뀐다. 그래서 같은 입력이면 같은 이름이 나오게 하고, 다른 이름이 궁금한 사람을 위해 “다시 뽑기” 버튼을 따로 달았다.

    코드를 몰라도 “만약에”만 알면 달라지는 것

    조건문을 알고 나서 가장 크게 달라진 건 AI와의 대화였다. 전에는 “결과가 이상해”라고만 했다. 이제는 “결과 계산에서 점수가 같을 때 처리가 빠진 것 같아”라고 말할 수 있다. 문제의 위치를 짚어 주니 AI의 답도 훨씬 정확해졌다.

    코딩을 모르는 분께 드리고 싶은 팁은 하나다. AI에게 기능을 부탁할 때 “만약 ○○이면 ○○해 줘. 아니면 ○○해 줘.” 이 모양으로 말해 보자. 예를 들어 “만약 사진을 안 올리면 기본 강아지 그림을 보여 줘”처럼 말이다. 이것만으로 AI가 엉뚱한 걸 만드는 일이 확 줄어든다. 코드를 직접 쓰지 못해도, 앱이 생각하는 방식을 아는 것만으로 충분하다.


    이전 글: 질문 7개로 집사 유형을 맞히는 테스트 앱 만드는 법
    다음 글: 테스트 결과를 집사 작위증으로! 받고 싶어지는 결과 화면 만드는 법

  • 질문 7개로 집사 유형을 맞히는 테스트 앱 만드는 법

    질문 7개로 집사 유형을 맞히는 테스트 앱 만드는 법

    작성자: 컴맹 집사

    대표 이미지: 7개 질문 중 두 번째 질문 화면 (출처: 왕립 개집사협회 앱 2026년 9월 19일 버전 화면, 직접 캡처)

    이 글에서 얻는 것

    • 이런 분께 질문에 답하면 유형이 나오는 테스트를 만들고 싶은 분
    • 핵심 답 보기마다 점수를 줄 유형을 정해 두고, 고를 때마다 1점씩 더해 가장 높은 유형을 결과로 보여 준다
    • 바로 쓰는 팁 질문은 “누구나 겪어 본 상황인가, 보기끼리 확실히 다른가, 답하면서 웃을 수 있는가”로 거르자

    “어떻게 답해도 비슷한 작위만 나와.”

    첫 버전을 해 본 친구의 말이다. AI가 처음 만들어 준 앱은 질문도 있고 결과도 있었지만, 질문과 결과가 어떻게 이어지는지는 내가 신경 쓰지 않았다. 그 연결을 AI에게 맡겨 두니 결과가 한쪽으로 쏠렸다.

    테스트 앱의 핵심은 질문 → 답 → 결과의 연결이다. 이 글은 왕립 개집사협회 앱에서 그 연결을 처음부터 다시 설계한 과정을 적는다.

    무엇을 묻는 테스트인가부터 정했다

    처음 헷갈렸던 건 “누구를 진단하느냐”였다. 폐하(강아지)의 성격은 앞 화면에서 보호자가 직접 고른다. 그러니 질문 7개는 폐하를 모시는 나, 즉 집사가 어떤 사람인지를 묻는 질문이어야 했다. 이 방향을 정하자 질문 후보를 고르는 기준도 분명해졌다.

    질문 개수는 왜 7개였나

    처음에는 10개를 생각했다. 직접 해 보니 8번째쯤에서 지루해졌다. 반대로 5개는 결과가 너무 가볍게 느껴졌다. AI에게 물으니, 가볍게 즐기는 테스트는 대체로 1분 안팎에 끝나는 게 좋고, 질문 하나에 5~8초쯤 걸린다고 봐서 7~10개가 적당하다고 했다. 다만 이 숫자는 AI의 일반적인 답이라, 나는 직접 시간을 재 보았다. 7개가 1분이 채 안 걸렸다. 첫 화면의 “정보 입력 → 질문 7개 → 작위증 발급” 순서와도 잘 맞았다.

    질문을 고른 기준

    AI에게 후보 질문을 20개쯤 받은 뒤 아래 기준으로 걸렀다. 후보는 제미나이와 챗GPT에서 각각 받아 겹치는 것과 참신한 것을 비교했다.

    1. 반려인이라면 누구나 겪어 본 상황인가. 산책, 목욕, 간식처럼 누구나 떠올릴 수 있어야 한다.
    2. 세계관 말투로 물을 수 있는가. “강아지가 목욕을 싫어하면?” 대신 “폐하가 목욕을 단호히 거부하신다면?”처럼 묻는다.
    3. 보기끼리 확실히 다른가. 보기 두 개가 비슷하면 사용자가 고민만 한다.
    4. 재미있는가. 답하면서 “이거 완전 나잖아” 하고 웃을 수 있어야 한다.

    최종 7개는 이렇다.

    1. 산책 시간이 되었을 때, 나는?
    2. 폐하가 목욕을 단호히 거부하신다면?
    3. 왕실 장난감이 감쪽같이 사라졌다!
    4. 폐하가 초롱초롱한 눈으로 간식을 요구하신다.
    5. 폐하와 함께하는 시간은 나에게?
    6. 왕실 업무가 산더미처럼 밀렸다!
    7. 새벽 세 시, 폐하의 갑작스러운 명령이 내려졌다.

    집사 유형 7가지와 작위 5단계

    결과는 두 겹으로 나오게 했다. 먼저 집사 유형이 정해지고, 유형에 따라 작위가 정해진다.

    진단 결과로 나온 집사 유형과 작위
    점수에 따라 집사 유형과 작위가 정해진다
    출처: 왕립 개집사협회 앱 2026년 9월 19일 버전 화면, 직접 캡처
    집사 유형 받는 작위
    전략적 회피형 집사 1단계 견국 수습집사
    간식 협상형 집사 2단계 왕실 생활협력관
    과잉보호형 집사 / 왕실 기록형 집사 3단계 왕실 돌봄근위관
    무조건 충성형 집사 / 산책 원정대장 4단계 발바닥 궁정대신
    평화 유지 전문관 5단계 왕실 총집사

    처음에는 작위를 “1등급, 2등급”으로 표시했다. 보통 “1등급”은 가장 높은 것으로 받아들여진다. 우리 앱에서 1은 가장 처음 단계인 수습집사라서 헷갈렸다. 그래서 “등급” 대신 “단계”로 바꿨다. 단어 하나를 바꾸자 오해가 사라졌다.

    보기마다 점수를 매기는 방식

    AI에게 “질문 답에 따라 일곱 가지 유형이 골고루 나오게 하려면 어떻게 설계해?”라고 묻자, 가장 흔한 방식으로 점수 방식을 알려 줬다.

    • 각 질문의 보기 네 개는 어떤 집사 유형에 점수를 주는지 정해 둔다.
    • 사용자가 보기를 고를 때마다 그 유형에 1점을 더한다.
    • 일곱 문제가 끝나면 점수가 가장 높은 유형이 결과가 된다.

    1번 질문은 이렇게 설계했다.

    보기 점수가 가는 유형
    알람보다 먼저 목줄을 들고 대기한다 산책 원정대장
    폐하의 눈치를 보며 슬쩍 시간을 확인한다 무조건 충성형
    “오늘은 날씨가 좀…” 하며 협상을 시도한다 전략적 회피형
    오늘의 코스와 시간을 기록해 둔다 왕실 기록형

    첫 버전에서 결과가 쏠렸던 이유도 이때 알았다. 처음에는 보기마다 1~4점을 주고 합계로 결과를 나눴는데, 대부분 사람이 중간쯤 답하니 합계가 가운데 구간에 몰렸다. 게다가 가장 높은 5단계 작위는 처음부터 결과로 나오지 않게 짜여 있었다. 유형별로 점수를 따로 모으는 방식으로 바꾸고, 다섯 단계 모두 결과로 나올 수 있게 연결을 다시 짜자 결과가 골고루 나뉘었다.

    일곱 유형이 골고루 나오는지 점검했다

    질문 7개 × 보기 4개 = 28개 보기가 각각 어느 유형에 점수를 주는지 표로 세어 보았다. 한 유형이 너무 자주 나오면 그 유형만 결과로 몰리고, 너무 적게 나오면 거의 볼 수 없는 유형이 된다. 몇몇 보기의 유형을 바꿔 균형을 맞췄다. 이 표 작업은 AI에게 세어 달라고 부탁하면 금방 끝났다.

    질문을 코드 속 목록으로 관리하기

    질문을 고칠 때마다 코드 여기저기를 뒤지는 게 불편했다. AI에게 “질문과 보기를 한 곳에 모아 관리하기 쉽게 바꿔 줘”라고 하자, 질문과 문구만 모아 둔 데이터 파일을 만들어 줬다.

    const QUESTIONS = [
      { q: '산책 시간이 되었을 때, 나는?', options: [
        { t: '알람보다 먼저 목줄을 들고 대기한다', type: 'walk' },
        { t: '폐하의 눈치를 보며 슬쩍 시간을 확인한다', type: 'loyal' },
        { t: '“오늘은 날씨가 좀…” 하며 협상을 시도한다', type: 'evade' },
        { t: '오늘의 코스와 시간을 기록해 둔다', type: 'record' } ] },
      // 2번~7번 질문도 같은 모양으로 이어진다
    ];
    

    여기서 배열(array)을 처음 배웠다. (출처: MDN 웹 문서, Array) 대괄호 [ ] 안에 여러 개를 순서대로 담아 두는 목록이다. 질문 7개가 하나의 목록에 차례로 들어 있고, 각 질문 안에는 보기 4개의 목록이 또 들어 있다. type에 적힌 영어 이름이 그 보기가 점수를 주는 집사 유형이다.

    이렇게 바꾸고 나니 좋은 점이 컸다.

    • 질문 문구를 고칠 때 이 데이터 파일만 보면 된다. 화면을 움직이는 코드는 건드릴 필요가 없다.
    • 질문을 하나 더 넣고 싶으면 같은 모양으로 한 덩어리만 추가하면 된다.
    • 진행도(3/7)도 목록 길이를 세서 자동으로 표시된다.
    • 나중에 영어판, 일본어판을 만들 때도 이 파일만 언어별로 따로 만들면 됐다.

    코드를 몰라도 이 목록 부분은 문서처럼 읽을 수 있었다. 앱 전체에서 내가 직접 고치는 첫 부분이 됐다.

    직접 해 보며 조정한 것

    • 보기 순서: 특정 유형의 보기가 늘 같은 자리에 있으면 사용자가 눈치챈다. 질문마다 순서를 섞었다.
    • 보기 길이: 너무 길면 휴대폰에서 두세 줄로 넘어간다. 한 줄 안에 들어오도록 줄였다.
    • 웃음 포인트: “내일의 나에게 위임한다”, “못 들은 척 눈을 질끈 감는다” 같은 보기는 반응이 좋았다. 세계관의 톤인 “귀엽고 따뜻하게, 위트는 살짝”을 지키려고 날 선 표현은 뺐다.

    남은 문제는 마지막 계산이었다. 점수가 가장 높은 유형을 어떻게 고를지, 점수가 같으면 어떻게 할지. 여기서 처음으로 조건문을 이해하게 됐다.


    이전 글: 3초 안에 마음을 잡아라! 앱 첫 화면 만드는 법
    다음 글: 조건문, “만약에” 한 마디면 끝! 앱이 알아서 결과를 고르는 원리

  • 3초 안에 마음을 잡아라! 앱 첫 화면 만드는 법

    3초 안에 마음을 잡아라! 앱 첫 화면 만드는 법

    작성자: 컴맹 집사

    대표 이미지: 하루 만에 첫 화면에 그림 배너를 넣어 분위기를 바꿨다 (출처: 앱의 시기별 화면을 직접 캡처해 비교 이미지로 제작)

    이 글에서 얻는 것

    • 이런 분께 앱이나 페이지 첫 화면을 어떻게 꾸밀지 고민하는 분
    • 핵심 답 첫 화면은 무슨 앱인지, 해 보고 싶은 분위기, 걸리는 시간, 눌러야 할 버튼 네 가지를 보여 줘야 한다. 첫 버전은 둘이 빠져 친구가 망설였다
    • 바로 쓰는 팁 AI에게 디자인을 맡길 때는 한 가지만 받지 말고 비교안을 받아 고르는 방식이 가장 효과적이었다

    친구에게 링크를 보내고 옆에서 지켜본 적이 있다. 친구는 앱을 열고 1~2초쯤 화면을 보다가, 스크롤을 한 번 내리고 다시 올린 뒤에야 시작 버튼을 눌렀다.

    그 몇 초 동안 친구는 “이게 뭐 하는 앱이지?”를 고민하고 있었다. 첫 버전의 시작 화면에는 제목 한 줄과 버튼 하나뿐이었다. 그날부터 첫 화면을 다시 만들었다.

    첫 화면이 해야 하는 일

    AI에게 “테스트형 앱의 첫 화면에 꼭 있어야 하는 게 뭐야?”라고 물었다. 받은 답을 내 앱에 맞게 정리하니 네 가지였다.

    1. 무슨 앱인지 한눈에 알려 준다. (제목과 부제)
    2. 해 보고 싶게 만든다. (그림, 분위기)
    3. 얼마나 걸리는지 알려 준다. (질문 7개, 1분)
    4. 무엇을 눌러야 하는지 분명하게 보여 준다. (시작 버튼)

    첫 버전에는 1번과 4번만 있었다. 2번과 3번이 빠지니 친구가 망설였던 것이다.

    문구부터 다시 썼다

    디자인보다 문구를 먼저 정했다. AI에게 후보를 여러 개 받고 그중에서 골랐다.

    • 위쪽 작은 글씨: Royal Kennel Butler Association (RKBA)
    • 제목: 왕립 개집사협회
    • 한 줄 소개: “우리 집 강아지가 왕이라면, 나는 어떤 집사일까?”
    • 진행 안내: 정보 입력 → 질문 7개 → 작위증 발급
    • 버튼: 나도 왕실 집사 되기

    “테스트 시작”보다 “나도 왕실 집사 되기”가 앱의 세계관과 잘 어울렸다. 버튼 문구 하나로 분위기가 달라진다는 걸 이때 알았다.

    디자인을 요청한 방법

    디자인을 말로 설명하는 게 가장 어려웠다. “예쁘게 해 줘”라고 하면 무난하지만 개성 없는 화면이 나왔다. 몇 번 시도한 끝에 효과가 있었던 건 분위기, 색, 구성, 조건을 구체적으로 말하는 방식이었다.

    첫 화면 디자인을 바꿔 줘.
    [분위기] 왕실 집사 임명식, 하지만 귀엽고 따뜻하게. 날 선 풍자는 빼고 위트는 살짝만.
    [색] 따뜻한 크림색 배경, 금색 포인트, 진한 색 글자.
    [구성] 위에서부터 왕관 그림 → 제목 → 부제 → 안내 문구 → 시작 버튼.
    [버튼] 금색, 크고 둥글게, 엄지로 누르기 편하게.
    [조건] 휴대폰 세로 화면 기준. 다른 화면과 기능은 건드리지 마.
    

    처음에는 그림 없이 이모지(👑)로 시작했다. 이미지 파일은 나중에 준비해도 됐다. 이모지는 휴대폰마다 모양이 조금 다르지만, 첫 화면의 분위기를 잡는 데는 충분했다.

    나중에는 배경을 이미지 생성 AI로 만들었다. 첫 시안에는 커다란 왕관 그림이 들어갔는데, 원래 쓰던 왕관 이모지보다 어색해 보였다. 그래서 “왕관은 그대로 두고 밋밋한 배경만 알록달록하게”로 요청을 바꿨고, 발바닥·하트·뼈다귀가 흩뿌려진 배경을 골랐다. 배경이 화려해진 만큼 글자가 묻히지 않도록 아래로 갈수록 배경을 옅게 처리했다.

    CSS를 조금 알게 됐다

    디자인을 고치다 보니 AI가 바꾸는 부분이 매번 CSS라는 걸 알게 됐다. (출처: MDN 웹 문서, CSS) 처음 앱 코드를 받았을 때 “화면의 옷”이라고 배웠던 부분이다. 자주 보이는 몇 가지는 뜻을 알게 됐다.

    CSS 속성 뜻 내가 쓴 예
    background 배경색 따뜻한 크림색
    color 글자색 진한 파란색 제목
    font-size 글자 크기 제목은 크게
    padding 안쪽 여백 버튼 안쪽을 넉넉하게
    border-radius 모서리 둥글기 버튼을 알약 모양으로

    이걸 알고 나니 간단한 건 직접 고칠 수 있었다. 버튼 색을 조금 밝게 하고 싶을 때 AI에게 묻지 않고 색 코드만 바꿔 봤다. 망가질까 봐 늘 커밋을 먼저 해 두었다.

    글꼴을 바꾸니 분위기가 달라졌다

    기본 글꼴은 너무 평범했다. AI에게 왕실 분위기에 어울리는 무료 한글 글꼴을 묻자, 누구나 쓸 수 있는 무료 공개 글꼴(OFL 라이선스)을 추천받았다.

    주의할 점도 있었다. 한글 글꼴은 파일이 커서 그대로 쓰면 앱이 느려진다. 그래서 앱에서 실제로 쓰는 글자만 골라 담은 작은 글꼴 파일을 만들어 앱 안에 함께 넣었다. 외부 사이트에서 글꼴을 불러오지 않으니 속도도 빨라졌다. 대신 문구에 새 글자가 생기면 글꼴 파일을 다시 만들어야 한다. 무료 글꼴이라도 사용 조건(라이선스)은 한 번 확인하는 게 좋다.

    휴대폰에서 확인한 것

    크롬 F12의 기기 툴바로 여러 화면 크기를 확인했다. 첫 화면에서 특히 본 것은 이것들이다.

    • 스크롤 없이 시작 버튼이 보이는가. 작은 화면에서는 버튼이 아래로 밀려 안 보였다. 그림 크기와 여백을 줄여 해결했다.
    • 버튼이 엄지로 누르기 편한가. 너무 작거나 화면 맨 위에 있으면 불편하다.
    • 글자가 어색하게 끊기지 않는가. 한 줄 소개는 “왕이라면,” 뒤에서 줄이 바뀌도록 맞췄다.
    • 가로로 돌렸을 때 크게 깨지지 않는가. 완벽하진 않아도 쓸 수는 있게 했다.

    첫 화면에 넣지 않기로 한 것

    넣고 싶은 것은 많았다. 참여자 수, 인기 작위 순위, 배경 음악. 하지만 첫 화면이 복잡해지면 사람들은 다시 “뭘 눌러야 하지?”로 돌아간다. 그래서 시작 버튼 하나에 시선이 모이도록 나머지는 뺐다. 참여자 수 같은 기능은 서버가 필요해서 지금 단계에서는 만들기도 어려웠다.

    바꾼 뒤의 반응

    새 첫 화면을 배포하고 다른 친구에게 링크를 보냈다. 이번에는 열자마자 버튼을 눌렀다. 나중에 물어보니 “내가 어떤 집사일지 궁금해서 바로 눌렀다”고 했다. 기능은 하나도 바뀌지 않았는데 첫인상이 달라졌다.

    한참 뒤에 다시 손본 것

    첫 화면은 한 번에 끝나지 않았다. 앱을 쓰다 보니 제목 위 왕관이 작고, 버튼 글자가 흐리고, 버튼 배경이 화면 배경과 비슷해서 버튼처럼 보이지 않는다는 게 눈에 들어왔다. 그래서 왕관과 제목을 키우고, 버튼 글자를 크고 진하게 바꾸고, 버튼 배경을 금색으로 채웠다. 금색이 너무 진해 보여서 한 톤 옅은 금색으로 다시 조정했다. 디자인은 한 번에 정답을 찾는 게 아니라 보고, 고치고, 다시 보는 일이었다.

    현재 왕립 개집사협회 앱 첫 화면
    한참 뒤에 다시 손본 지금의 첫 화면
    출처: 직접 캡처한 화면(2026년 10월 12일)

    비교 요청이 가장 효과적이었다

    첫 화면 작업에서 가장 효과가 있었던 건 비교 요청이었다. “디자인 시안을 세 가지로 만들어 줘. 각각 다른 파일 이름으로”라고 하면 분위기가 다른 세 가지 버전이 나온다. 세 파일을 나란히 열어 보고 마음에 드는 것을 고른 뒤, 나머지 두 개에서 좋았던 부분을 가져와 합쳤다. 말로 “예쁘게”를 설명하는 것보다 보고 고르는 것이 훨씬 쉬웠다. 남은 시안 파일은 지워서 폴더를 정리했다.

    첫 화면을 지나면 이 앱의 핵심인 질문이 나온다. 다음 글에서는 질문 7개를 어떻게 만들고, 답이 어떻게 결과로 이어지게 했는지 적었다.


    이전 글: 빨간 글씨 가득한 배포 오류, 겁먹지 않고 해결한 순서
    다음 글: 질문 7개로 집사 유형을 맞히는 테스트 앱 만드는 법

  • 빨간 글씨 가득한 배포 오류, 겁먹지 않고 해결한 순서

    빨간 글씨 가득한 배포 오류, 겁먹지 않고 해결한 순서

    작성자: 컴맹 집사

    대표 이미지: 오류 해결은 증상을 살피고 원인을 찾는 진찰과 비슷했다 (사진: free-photos / Pixabay)

    이 글에서 얻는 것

    • 이런 분께 배포 오류나 하얀 화면 앞에서 겁부터 나는 분
    • 핵심 답 실패한 배포는 기존 앱을 망가뜨리지 않는다. Vercel이 Error면 Build Logs, Ready인데 화면이 이상하면 F12 콘솔에서 빨간 줄을 찾는다
    • 바로 쓰는 팁 빨간 줄과 그 주변을 복사하고, 바로 전에 한 일을 함께 적어 AI에게 보내자

    Vercel에서 처음 보는 색이었다. 늘 초록색으로 뜨던 Ready 자리에 빨간색 Error가 떠 있었다. 눌러 보니 영어 기록이 길게 이어지고, 그 끝에 빨간 줄 몇 개가 있었다.

    뭔가 크게 망가뜨린 것 같아서 심장이 쿵 했다. 결론부터 말하면, 이 오류는 30분 만에 해결됐고 앱은 한 번도 멈추지 않았다. 아래에는 오류 앞에서 침착하게 대처한 순서를 적었다.

    먼저 안심해도 되는 사실

    AI에게 캡처를 보여 주자 가장 먼저 이런 말을 해 줬다.

    Vercel은 새 배포가 실패하면 이전에 성공한 배포를 그대로 유지합니다. (출처: Vercel 문서, 배포 개요) 지금 사용자가 보는 앱은 망가지지 않았습니다.

    실제로 휴대폰으로 링크를 열어 보니 앱은 멀쩡했다. 새 버전이 올라가는 데 실패했을 뿐, 기존 버전은 그대로 서비스되고 있었다. 이 사실 하나로 마음이 훨씬 가라앉았다.

    오류에는 크게 두 종류가 있었다.

    • 배포 자체가 실패하는 오류: Vercel에 빨간 Error가 뜬다. 기존 앱은 유지된다.
    • 배포는 성공했는데 앱이 이상한 오류: Vercel에는 초록 Ready가 뜨는데, 화면이 하얗거나 버튼이 눌리지 않는다. 사용자가 바로 망가진 앱을 보므로 이쪽이 더 급하다.

    두 가지 모두 겪었고, 해결 방법이 조금 달랐다.

    사례 1: 배포가 실패했다 (Error)

    원인을 만든 수정

    그날 AI의 제안으로 vercel.json이라는 설정 파일을 하나 만들었다. 주소 끝에 /about 같은 것을 붙였을 때도 앱이 열리게 하려는 설정이었다. AI가 준 내용을 메모장에 붙여 넣어 저장하고 푸시했다.

    오류 기록 읽기

    Vercel에서 실패한 배포를 누르면 Build Logs(빌드 기록)가 나온다. 처음엔 전부 읽으려다 포기했다. AI가 알려 준 요령은 간단했다.

    • 맨 아래부터 위로 읽는다.
    • Error, Failed, Invalid 같은 단어가 있는 줄을 찾는다.
    • 그 줄과 바로 위아래 몇 줄을 복사한다.

    내 경우 빨간 줄에는 vercel.json 파일이 올바르지 않다는 내용이 적혀 있었다.

    AI에게 오류를 설명하는 방법

    Vercel 배포가 실패했어.
    [바로 전에 한 일] vercel.json 파일을 새로 만들어서 푸시했어.
    [오류 기록] (복사한 빨간 줄들)
    [vercel.json 내용] (파일 전체)
    원인과 고치는 방법을 초보자에게 설명하듯 알려 줘.
    

    AI는 금방 원인을 찾았다. 메모장에 붙여 넣는 과정에서 쉼표 하나가 빠져 있었다. JSON이라는 형식은 쉼표나 괄호 하나만 틀려도 전체를 읽지 못한다고 했다. 쉼표를 넣고 다시 푸시하자 초록색 Ready가 떴다.

    여기서 배운 것

    “바로 전에 무엇을 했는지”를 함께 말하는 것이 가장 중요했다. 오류 기록만 보내면 AI도 여러 가능성을 늘어놓는다. “vercel.json을 새로 만들었다”는 한 줄이 원인을 거의 짚어 줬다. 커밋을 작게 나눠 둔 습관도 도움이 됐다. 마지막 커밋에 바뀐 것이 하나뿐이니 범인도 하나뿐이었다.

    사례 2: 배포는 됐는데 화면이 하얗다

    더 당황스러운 쪽은 이쪽이었다. Vercel은 Ready인데, 앱을 열면 시작 화면만 나오고 시작 버튼을 눌러도 반응이 없었다.

    노트북 앞에서 머리를 감싼 사람
    화면이 하얗게 나올 때의 막막함
    사진: pexels / Pixabay

    개발자 도구의 콘솔 열기

    AI가 알려 준 방법은 개발자 도구였다. 크롬에서 F12를 누르면 창이 열리는데, 그중 Console(콘솔) 탭을 누른다. 콘솔은 앱이 동작하면서 남기는 알림장 같은 곳이다. 문제가 생기면 여기에 빨간 글씨로 기록이 남는다.

    콘솔에는 빨간 줄이 하나 있었다. Uncaught SyntaxError로 시작하는 문장과 함께 index.html:214라는 표시가 있었다. 214번째 줄 근처에 문법 오류가 있다는 뜻이었다.

    원인은 따옴표

    그 줄을 AI에게 보여 주니, 결과 설명 문구에 넣은 작은따옴표가 문제라고 했다. “귀족의 ‘품격’을 갖춘 강아지”처럼 문장 안에 따옴표를 넣었는데, 코드에서도 따옴표로 문장을 감싸고 있어서 문장이 중간에 끊긴 것으로 인식됐다. JavaScript는 한 곳이 멈추면 그 뒤의 동작이 전부 멈추기 때문에 버튼이 반응하지 않았던 것이다.

    따옴표를 다른 모양(「품격」)으로 바꾸자 해결됐다.

    오류 해결 순서

    두 번의 경험 뒤에 정한 순서다. 모니터 옆에 붙여 두었다.

    1. 당황하지 않는다. 실패한 배포는 기존 앱을 망가뜨리지 않는다.
    2. 어디서 문제가 났는지 본다. Vercel이 Error면 Build Logs, Ready인데 이상하면 F12 콘솔.
    3. 빨간 줄과 그 주변을 복사한다.
    4. 바로 전에 한 일을 같이 적어서 AI에게 보낸다.
    5. 고친 뒤 내 컴퓨터에서 먼저 확인하고 푸시한다.
    6. 급하면 Vercel에서 이전 배포로 되돌려 두고 천천히 고친다.

    AI의 답이 틀릴 때도 있었다

    AI가 한 번에 맞힌 경우만 있던 건 아니다. 한 번은 세 번 연속 다른 방법을 제시했는데 모두 효과가 없었다. 그럴 때 도움이 된 방법이 있었다.

    • 새 대화를 연다. 한 대화에서 계속 시도하면 AI가 앞의 틀린 가정에 갇힌 것처럼 보였다.
    • 처음부터 상황을 다시 설명한다. 코드 전체, 오류 전체, 한 일 전체.
    • “가능한 원인을 모두 나열하고, 하나씩 확인하는 방법을 알려 줘”라고 요청한다. 한 번에 고치려 하지 말고 범위를 좁혀 가는 방식이다.

    이 방법으로 대부분 해결됐다.

    배포하고 고치는 흐름이 손에 익었으니, 이제 앱의 기능을 하나씩 다듬을 차례다. 가장 먼저 손본 건 사용자가 처음 만나는 화면이었다.


    이전 글: 배포한 앱, 어떻게 고치지? 컴맹이 정착한 5단계 수정 루틴
    다음 글: 3초 안에 마음을 잡아라! 앱 첫 화면 만드는 법