본문 바로가기

전체 글

(140)
모바일 앱 점검 공지와 강제 업데이트 설계 (예고, 점검 중 차단, 최소 빌드와 권장 빌드) 서버와 함께 도는 모바일 앱에서 점검을 예고하고, 점검 중에는 접속을 막고, 끝나면 옛 버전 사용자를 새 버전으로 업데이트하게 하는 흐름을 서버 쪽 기준으로 설계하는 방법입니다.개인 게임 앱에 서버 규칙이 바뀌는 업데이트를 내보내려니, 그동안은 점검 공지도 업데이트 안내도 없었다는 걸 알았습니다. 서버만 바꾸면 옛 앱과 규칙이 어긋나고 앱만 먼저 나가도 마찬가지라, 점검 시간을 잡고 그 안에서 둘을 맞추는 장치부터 만들었습니다.- 점검 상태와 빌드 기준은 서버가 들고 있고, 앱은 요청마다 자기 빌드 번호를 보낸다- 점검 중에는 게임 요청을 503, 최소 빌드보다 낮은 앱의 진행 요청은 426 으로 막는다- 이 장치가 없는 옛 앱도 기존 응답 형식 안에서 안내를 받게 따로 챙긴다1. 왜 필요한가: 앱과 서..
구글 플레이 콘솔 관리형 게시로 심사 통과와 공개 시점 떼어 놓기 (트랙 상태 completed 인데 스토어에 없는 이유) 플레이 콘솔에 앱 업데이트를 올렸는데 언제 공개될지 몰라 서버 배포 시점을 못 정하거나, API 로 본 트랙 상태는 completed 인데 스토어에는 앱이 안 보일 때, 관리형 게시로 공개 시점을 직접 정하는 방법입니다.개인 게임 앱을 처음 플레이스토어에 낼 때, 심사를 보내 놓고 플레이 개발자 API 로 프로덕션 트랙을 읽어 보니 상태가 completed 였습니다. 출시가 끝난 줄 알았는데 스토어 주소를 열어 보니 404 였고, 다음 날 다시 보니 이미 공개돼 있었는데 그 전날 오후에 공개됐다는 것도 그때 알았습니다.- API 의 트랙 상태 completed 는 출시 설정을 마쳤다는 뜻이지 심사를 통과해 공개됐다는 뜻이 아니다- 공개 여부는 스토어 상세 페이지가 200 으로 열리는지로 확인하는 게 확실..
출시 전 iOS 앱에서 애드몹(AdMob) 보상형 광고가 안 나올 때 (실제 광고 단위 no fill과 시험 단위 나누기) 아직 앱스토어에 공개하지 않은 iOS 앱을 테스트플라이트로 깔아 보상형 광고 버튼을 눌렀는데, 시험 광고는 잘 나오다가 실제 광고 단위로 바꾸자 광고가 아예 안 뜰 때 원인과 대처를 알아보는 글입니다.개인 게임 앱을 안드로이드에 먼저 내고 iOS 판을 준비하면서, 아이폰 시험판에도 출시 때 쓸 실제 보상형 광고 단위를 넣어 봤습니다. 그런데 광고 버튼을 누르면 광고 대신 "광고를 끝까지 보면 받을 수 있어요" 안내만 떴고, 광고를 본 적도 없는데 끝까지 보라는 말이 나오니 무엇이 문제인지 헷갈렸습니다.- 실제 광고 단위는 앱이 애드몹 검토(앱 준비 상태)를 통과하기 전까지 광고 게재가 제한된다- 그래서 출시 전 빌드는 구글 시험 광고 단위를 쓰고, 출시 빌드만 실제 단위를 넣도록 나눴다- 안내 문구도 못..
Flutter 고정 헤더 아래로 특정 섹션까지 스크롤이 안 될 때 (getOffsetToReveal 이 안쪽 ListView 를 잡는 문제와 화면 좌표로 animateTo) 플러터(Flutter)에서 SliverPersistentHeader(pinned: true) 로 고정한 헤더 아래에 긴 목록을 두고, 헤더의 버튼을 누르면 목록 속 특정 섹션까지 내려가게 하려는데 엉뚱한 곳으로 가거나 아예 안 움직일 때 해결하는 방법입니다.개인 게임 앱의 장비 화면은 위에 전투 화면과 "지금 장착한 무기, 탈것, 방패" 줄이 고정돼 있고, 그 아래로 무기, 탈것, 방패 묶음이 길게 이어집니다. 장착 줄의 칸을 누르면 아래 그 묶음이 장착 줄 바로 밑에 오도록 내려가게 하고 싶었는데, 처음 짠 코드는 위치 계산이 맞지 않았습니다.- 원인은 스크롤이 두 겹인데 위치를 재는 쪽과 움직이는 쪽이 서로 다른 뷰포트를 잡은 것이었다- RenderAbstractViewport.of 는 가장 가까운,..
애드몹(AdMob) 최대 광고 콘텐츠 등급을 바꾸면 수익이 얼마나 줄까 (G, PG, T, MA 차이와 전체이용가 앱의 선택) 애드몹으로 광고를 붙인 앱에서 최대 광고 콘텐츠 등급을 G, PG, T, MA 중 무엇으로 둘지 고민될 때, 등급마다 무엇이 걸러지고 노출과 수익이 얼마나 줄어드는지 알아보는 글입니다.전체이용가로 등록한 개인 게임 앱에 보상형 광고를 넣으면서 출시 전 점검을 하다 보니, 12세 등급인 다른 게임에서 청소년이용불가 광고가 나오는 걸 본 적이 있었습니다. 앱 등급에 맞는 광고만 나오게 하려면 애드몹의 최대 광고 콘텐츠 등급을 정해야 하는데, 가장 엄격한 G 로 두려니 수익이 꽤 줄어든다는 예상치가 떴습니다.- 등급은 G, PG, T, MA 네 단계이고, 낮게 잡을수록 걸러지는 광고가 많아진다- 콘솔에서 등급을 고르면 노출과 수익이 얼마나 줄지 예상치를 보여 준다- 전체이용가 앱이라면 G 와 T 사이의 PG ..
숫자가 바뀔 때마다 옆 칸이 들썩일 때 (Flutter 가변폭 숫자와 tabularFigures 가 안 먹는 글꼴) 플러터(Flutter) 화면에서 점수나 재화 숫자가 바뀔 때마다 그 칸의 폭이 조금씩 달라져 옆에 붙은 칸들이 흔들릴 때, 숫자 폭을 고정해 해결하는 방법입니다.개인 게임 앱 위쪽 막대에 골드, 재료, 가방 같은 칩을 나란히 두었는데, 골드가 오를 때마다 오른쪽 칩들이 좌우로 살짝살짝 움직였습니다. 숫자가 쉬지 않고 바뀌는 화면이라 그 떨림이 계속 눈에 걸렸습니다.- 원인은 글꼴의 숫자마다 폭이 달라서, 같은 자리 수여도 값에 따라 칩 폭이 바뀐 것이었다- 흔히 쓰는 FontFeature.tabularFigures() 는 글꼴에 tnum 기능이 없으면 아무 효과가 없다- 그래서 숫자 칸의 폭을 가장 넓은 숫자 기준으로 재서 고정했다1. 숫자 폭이 글꼴마다 다르다본문용 글꼴은 숫자 열 개의 폭을 똑같이 맞..
구글 클라우드(Google Cloud) 300달러 무료 크레딧이 Gemini API 비용에 안 빠질 때 (AI Studio 키와 Vertex AI 키 차이) 구글 클라우드 무료 체험 크레딧 300달러가 남아 있는데도 Gemini 로 이미지나 텍스트를 생성한 비용이 크레딧에서 빠지지 않고 따로 나갈 때, 원인이 무엇이고 어떻게 바꾸면 크레딧으로 쓸 수 있는지 알아보는 글입니다.게임 그림을 Gemini 이미지 모델로 대량으로 만들던 중이었습니다. 구글 클라우드에 가입하면 주는 300달러 크레딧(90일)이 있어서 그걸로 충당된다고 생각했는데, 다음 날 결제 보고서를 보니 크레딧은 거의 그대로이고 생성 비용은 다른 곳에서 빠져 있었습니다.- 같은 Gemini 모델이라도 어느 주소로 부르느냐에 따라 비용이 나가는 곳이 달랐다- AI Studio 에서 받은 키로 부른 Gemini API 사용분은 무료 크레딧 대상이 아니었다- Vertex AI 주소로 부른 사용분은 크레..
안드로이드에서 배경음 반복 재생 때 이음매가 뚝 끊길 때 (MediaPlayer 반복 무음과 ExoPlayer 한 곡 반복) 플러터(Flutter) 앱에서 audioplayers 로 배경음을 ReleaseMode.loop 반복으로 틀었는데, 안드로이드에서만 곡이 끝나고 처음으로 돌아가는 순간 소리가 뚝 끊기는 문제를 해결하는 방법입니다.개인 게임 앱에 70초 남짓한 배경음을 넣고 반복으로 틀어 두었는데, 플레이하다 보면 곡이 끝나고 새로 시작할 때마다 잠깐 끊기는 느낌이 났습니다. 음악이 이어져야 할 자리에서 박자가 한 번 빠지니, 게임 화면은 멀쩡한데도 어딘가 고장 난 것처럼 들렸습니다.- 원인은 음원 파일이 아니라 안드로이드 MediaPlayer 의 반복(setLooping) 이었다- 녹음해서 재 보니 반복할 때마다 81.75ms 무음이 끼어 있었다- 안드로이드만 ExoPlayer 의 한 곡 반복(REPEAT_MODE_ON..