Cheondi
개발 · Unity

공지와 티커가 서로 다른 언어로 보였다

언어 변경 뒤 서로 다른 데이터 경로의 공지와 티커가 어긋나는 문제를 갱신 정책으로 해결한 기록입니다.

  • #localization
  • #cache
  • #api

앱 언어를 일본어로 바꿨는데 상단 티커는 일본어, 공지 목록은 이전 언어로 남는 일이 있었다. 두 화면 모두 다국어 데이터를 사용했지만 티커는 언어 변경 때 다시 요청했고 공지는 앱 시작 캐시를 계속 사용했다. 번역 UI 문제가 아니라 데이터 갱신 정책의 차이였다.

같은 언어 설정을 보더라도 데이터가 만들어진 시점이 달랐다.

캐시 키에 언어가 빠져 있었다

공지 캐시는 항목 ID만 키로 사용해 어느 언어로 받은 내용인지 알 수 없었다. 언어와 콘텐츠 버전을 키에 포함했다.

string NoticeCacheKey(string language, long version)
    => $"notice:{language}:{version}";

서버가 번역을 제공하지 않는 언어에서는 기준 언어로 대체됐다는 상태도 같이 저장했다.

언어 변경을 데이터 이벤트로 다뤘다

텍스트 컴포넌트만 다시 그리지 않고 언어에 의존하는 데이터 공급자에게 갱신을 요청했다.

언어 변경
 -> 정적 UI 문구 갱신
 -> 공지 캐시 전환 또는 재조회
 -> 티커 스트림 재구독
 -> 현재 상세 화면 재바인딩

진행 중인 이전 언어 요청은 취소하거나 응답 적용 시 언어를 비교해 버렸다.

실시간 티커는 연결을 다시 맺는 동안 동일 항목이 중복으로 들어올 수 있었다. 항목 ID와 언어 버전을 기준으로 교체하고, 이전 구독이 완전히 끝났는지 확인했다. 정적 조회와 스트림은 갱신 방식이 달라도 최종 화면 상태 규칙은 같아야 했다.

혼합 상태를 잠깐이라도 보여줄지 정했다

새 공지를 받는 동안 이전 언어 내용을 유지하면 화면이 빠르지만 언어가 섞인다. 이 화면에서는 짧은 로딩 상태를 보여주고 완성된 새 언어 데이터로 한 번에 교체했다. 네트워크 실패 시에는 기준 언어로 대체됐음을 작게 알렸다.

공지 상세에서 목록으로 돌아올 때도 현재 언어의 캐시를 다시 사용하도록 확인했다.

언어를 연속으로 두 번 바꾸기, 오프라인에서 바꾸기, 상세 화면을 연 상태에서 바꾸기를 재현 시나리오로 만들었다. 단순한 한 번의 변경보다 요청 완료 순서가 뒤바뀌는 조건에서 문제가 잘 드러났다.

화면 언어는 여러 시스템의 합의였다

처음에는 전역 언어 값 하나를 바꾸면 모든 것이 따라올 거라 생각했다. 실제로는 정적 문자열, 캐시 API, 실시간 스트림이 각자 언어를 소비했다. 하나라도 갱신 규칙이 다르면 혼합 화면이 됐다.

이 경험 뒤 언어에 영향을 받는 자산과 데이터 경로를 목록으로 관리한다. 언어 변경은 UI 이벤트이면서 캐시 무효화와 네트워크 재구독을 포함하는 상태 전환이었다.