외부 URI로 앱의 특정 화면에 바로 진입하는 것.
composable<Detail>(
deepLinks = listOf(navDeepLink<Detail>(basePath = "https://example.com/detail"))
) { entry -> DetailScreen(entry.toRoute<Detail>().id) }
<activity android:name=".MainActivity">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="example.com" />
</intent-filter>
</activity>
커스텀 스킴 vs App Links
-
myapp://detail/42 — 커스텀 스킴
- 아무 앱이나 같은 스킴을 선언할 수 있다 (하이재킹 가능)
- 앱이 없으면 링크가 깨진다
-
https://example.com/detail/42 — App Links
- 도메인 소유를 서버로 증명한다 → 선택 다이얼로그 없이 바로 열린다
- 앱이 없으면 웹페이지가 열린다 (자연스러운 대체)
-
외부에 노출하는 링크는 App Links 가 맞다
도메인 검증
https://example.com/.well-known/assetlinks.json 을 올린다
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": { "namespace": "android_app",
"package_name": "com.example.app",
"sha256_cert_fingerprints": ["AB:CD:..."] }
}]
지문은 '실제 배포 서명' 이어야 한다
- Play 앱 서명을 쓰면 Play Console 의 지문을 넣는다 — 업로드 키가 아니다
- 이걸 헷갈려 "기기에서만 안 열린다" 가 가장 흔한 사고다
백스택이 비는 문제
딥링크로 상세 화면에 바로 들어가면 그 위에 아무것도 없다
- 뒤로가기를 누르면 앱이 그냥 닫힌다 (사용자는 목록을 기대한다)
Navigation 은 그래프의 startDestination 을 기준으로 합성 백스택을 만들어 준다 — 중첩 그래프 구조가 여기서 값을 한다
중첩 그래프
navigation<AuthGraph>(startDestination = Login) {
composable<Login> { ... }
composable<SignUp> { ... }
}
관련 화면을 묶으면
- popUpTo(AuthGraph) 로 흐름 전체를 한 번에 걷어낼 수 있다
- 그래프 범위 ViewModel 로 상태를 공유할 수 있다
테스트
adb shell am start -a android.intent.action.VIEW -d "https://example.com/detail/42"
면접 함정
- ❌ "autoVerify만 켜면 App Links가 된다" → 서버의
assetlinks.json과 지문이 맞아야 한다. - ❌ "딥링크는 사용자가 로그인했다고 가정해도 된다" → 미로그인 상태로 들어올 수 있다. 인증 분기를 반드시 둔다.