
얼마 전에 로그인 화면 만들다가, 아이디칸은 자동완성이 뜨는데 비밀번호칸만 텅 비어있더라고요. 키보드 위 제안 줄이 끝까지 안 나오는데 멘붕이 오더군요.
분명 contentType 도 넣었는데 말이죠. 처음엔 코드가 틀린 줄 알고 한참을 들여다봤는데, 알고 보니 코드 문제 반, 환경 문제 반이었습니다. 이 둘을 분리해서 봐야 길이 보였어요.
Compose 자동완성, contentType만으론 안 되던 이유
젯팩 컴포즈(Jetpack Compose) 1.8.0부터는 자동완성이 정식으로 들어왔습니다. 예전처럼 View 를 억지로 끼워 넣는 우회 코드, 이제 안 써도 돼요.
방법은 간단해요. Modifier.semantics 로 이 칸이 뭘 담는 칸인지 알려주기만 하면 됩니다.
TextField(
value = password,
onValueChange = { password = it },
modifier = Modifier.semantics {
// 로그인 화면이면 Password, 회원가입이면 NewPassword
contentType = ContentType.Password
}
)
회원가입 화면이라면 ContentType.NewPassword 를 쓰는 게 맞아요. 그래야 "강력한 비밀번호 생성" 제안이 뜨거든요.
근데 제 경우엔 이걸 넣었는데도 비밀번호칸만 비어있었습니다. 원인은 두 가지였어요. 하나는 예전 View 시절 자동완성 우회용으로 남겨뒀던 importantForAutofill 설정이 충돌하고 있던 것, 다른 하나는 에뮬레이터 안에 자동완성을 공급해줄 제공자가 아예 없던 거였습니다. 코드만 백날 들여다봐도 안 풀릴 수밖에 없었던 거죠.

Compose 1.12 credentialRequest로 키보드 제안 붙이기
contentType 은 "이 칸은 비밀번호 칸이야" 라고 OS 에 알려주는 역할까지입니다. 근데 거기서 한 발 더 나가서, 구글 비밀번호 관리자나 1Password 같은 여러 곳에 저장된 자격증명을 키보드 제안으로 직접 끌어오고 싶을 때가 있어요.
원래 이건 setPendingGetCredentialRequest 라는 API 로 했는데, 공식 문서상 View 객체 전용으로 명시돼 있었습니다. 그래서 순수 컴포즈 화면에서는 AndroidView 로 감싸는 번거로운 작업이 필요했지요.
컴포즈 1.12 alpha(alpha03)부터는 이게 달라졌어요. credentialRequest 라는 Semantics 가 추가돼서, AndroidView 래핑 없이 TextField 에 GetCredentialRequest 를 바로 연결할 수 있게 됐습니다. 다만 아직 alpha 단계라는 점은 미리 염두에 두시는 게 좋아요.
modifier = Modifier.semantics {
contentType = ContentType.Password
// alpha 단계 API — 정식 출시 시 시그니처가 바뀔 수 있어요
credentialRequest = GetCredentialRequest(
credentialOptions = listOf(
GetPasswordOption(), // 저장된 비밀번호
GetPublicKeyCredentialOption(requestJson) // 패스키
)
)
}
비밀번호 옵션과 패스키 옵션을 함께 넣으면, 사용자가 그 칸에 포커스하는 순간 둘 다 키보드 제안에 같이 떠요. 다만 정확한 속성명이나 시그니처는 alpha라서 바뀔 수 있으니, 쓰시기 전에 최신 릴리스 노트를 한 번 확인하시는 게 안전합니다.
Autofill과 Credential Manager는 어떻게 맞물릴까
여기서 헷갈리기 쉬운 게, Autofill 과 Credential Manager 가 따로 노는 것처럼 보인다는 점입니다. 근데 사실 둘은 역할이 나뉘어 있어요.
쉽게 설명하자면, Autofill 프레임워크는 OS 가 칸을 채워주는 "배달부" 예요. 칸이 어떤 데이터를 담는지(contentType) 알려주면 그걸 들고 와서 채워줍니다.
Credential Manager 는 비밀번호·패스키를 안전하게 보관하고 꺼내주는 "창고" 라고 보시면 되겠습니다. 이 창고에서 꺼낸 자격증명이 Autofill 이라는 배달부를 거쳐서 키보드 제안으로 사용자한테 노출되는 구조인 거죠. 그러니까 이 연결 구조를 이해하는 게 핵심이라고 봅니다.

에뮬레이터 자동완성, 제공자 설정부터 확인하세요
코드를 아무리 정석대로 짜도 제안이 안 뜨는 경우가 있어요. 저처럼 에뮬레이터에서 텅 빈 화면 보고 코드만 의심하는 일, 안 겪으셨으면 합니다.
기기 시스템 설정에 자동완성 서비스 제공자(예: 구글 비밀번호 관리자)가 등록돼 있지 않으면 코드가 맞아도 제안이 절대 안 떠요. 깨끗한 에뮬레이터는 이 제공자가 비어있을 때가 많습니다.
실제 채우기가 되는지는 눈으로 검증할 수 있어요. 자동완성이 들어간 칸은 View 시절과 똑같이 노란색 배경으로 하이라이트됩니다. 이 노란색이 뜨면 채우기가 제대로 동작한 거예요.
개인적으로는 에뮬레이터에서 이거 붙잡고 씨름하는 것보다, 구글 계정 로그인해둔 실기기 하나 물려두고 테스트하는 게 훨씬 빠르더라고요. 제공자가 기본으로 깔려 있어서 변수가 하나 줄어들기 때문입니다.

베타 API라 롤백 경로부터 확보했어요
마지막으로 한 가지만 짚고 가겠습니다. credentialRequest 는 아직 alpha 단계 API 예요. 정식 출시되면서 시그니처가 통째로 바뀔 위험이 있습니다.
그래서 저는 이 연동 코드를 별도 함수로 따로 빼두고, 기능 플래그를 하나 걸어서 언제든 끌 수 있게 해뒀어요. alpha 버전을 올렸다가 빌드가 깨지거나 제안이 안 뜨면, 플래그만 내려서 contentType 만 남은 안정 버전으로 되돌리는 거죠.
게다가 컴포즈 1.12 같은 최신 버전을 쓰려면 compileSdk 37, AGP 9 까지 빌드 환경을 통째로 올려야 할 수 있습니다. 이건 다른 라이브러리들과 줄줄이 얽히는 작업이라 만만치 않아요. 그러니 당장 운영 앱에 급하게 넣기보다, 별도 브랜치에서 충분히 검증하고 들어가시는 게 안전합니다.
결국 비밀번호칸 자동완성은 코드 한 줄 문제가 아니라, 채우기와 공급이 어디서 끊겼는지를 나눠서 봐야 풀리는 문제였습니다. 노란색 하이라이트 한 번 뜨는 거 보려고 반나절을 썼지만, 이 연결 구조를 알고 나니 다음부턴 어디부터 의심해야 할지 딱 잡히더라고요.

'Android 개발 > Jetpack Compose' 카테고리의 다른 글
| Compose adaptive 라이브러리(material3-adaptive)의 ListDetailPaneScaffold로 태블릿·폴더블 적응형 UI 구현 (0) | 2026.08.13 |
|---|---|
| Compose 1.11 대화면 대응 일지: 트랙패드가 따로 놀던 화면 손보기 (0) | 2026.08.09 |
| Compose 1.11 FlexBox API로 칩·태그 자동 줄바꿈, Row 47줄을 3줄로 줄인 후기 (0) | 2026.07.17 |
| Navigation 3로 갈아타 봤습니다 — 화면 백스택을 상태로 직접 들고 있게 된 자리 (1) | 2026.07.06 |
| 안드로이드 스크린샷 테스트 3종 비교 — Roborazzi·Paparazzi·Compose Preview 갈라 써본 한 주 (0) | 2026.07.05 |