프로젝트 맥락
본 글은 SwiftUI로 Apple Developer Academy_Challenge 2에서 개발 중인 ‘Re:ToU(오늘의 너)’ 앱을 기반으로 작성되었습니다.
‘Re:ToU’는 하루에 하나씩 감정과 회고를 기록하는 앱으로,
개인적인 기록이 포함되는 만큼 앱을 열 때 간단한 생체인증(Face ID / Touch ID)을 요구하도록 설계했습니다.
이 기능은 앱을 껐다 켤 때마다 자동으로 인증 절차가 실행되며, 다른 사람의 접근을 방지하기 위한 보안 UX의 핵심 역할을 합니다.
기능 설명
앱 실행 시 다음과 같은 흐름으로 동작합니다.
- 앱이 실행되면 인증 뷰를 먼저 띄움
- Face ID / Touch ID 인증을 시도
- 성공 시 메인 화면으로 진입
- 실패 시 다시 인증 시도 또는 앱 종료 유도
이 기능은 LocalAuthentication 프레임워크를 사용하며, SwiftUI와 연동하기 위해 별도 인증 뷰 모델을 구성했습니다.
시도 동기
초기에는 앱 실행 후 바로 메인 화면으로 진입하는 구조였고,
기록이 아무나 볼 수 있다는 점에서 보안적으로 문제가 있었습니다.
그래서 앱 실행 시 생체인증을 도입하려고 했지만,
SwiftUI에서 LocalAuthentication을 사용하는 예제가 적고,
앱의 Scene 단위 진입 흐름과 어떻게 연동할지 명확하지 않았습니다.
문제 발견
Face ID / Touch ID를 연동하면서 다음과 같은 문제를 마주했습니다.
- SwiftUI에서는 AppDelegate 없이 인증 시점 지정이 어려움
- 앱이 백그라운드 → 포그라운드로 돌아올 때 재인증 처리 누락
- 인증 실패 시 재시도 로직 누락으로 UX 불안정
문제 해결
1. LocalAuthentication 인증 함수 정의
import LocalAuthentication
class AuthViewModel: ObservableObject {
@Published var isAuthenticated = false
func authenticate() {
let context = LAContext()
var error: NSError?
if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
let reason = "기록을 열기 위해 인증이 필요합니다."
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason) { success, _ in
DispatchQueue.main.async {
self.isAuthenticated = success
}
}
} else {
// Face ID 미지원 기기 대응
DispatchQueue.main.async {
self.isAuthenticated = true
}
}
}
}
2. 인증 전용 View 구성
struct AuthenticationView: View {
@StateObject private var authViewModel = AuthViewModel()
var body: some View {
Group {
if authViewModel.isAuthenticated {
MainView() // 인증 완료 시 진입
} else {
VStack {
Text("Face ID 인증 중...")
ProgressView()
}
.onAppear {
authViewModel.authenticate()
}
}
}
}
}
3. 앱 진입 시 AuthenticationView 사용
@main
struct ReToUApp: App {
var body: some Scene {
WindowGroup {
AuthenticationView()
}
}
}
이 구조로 앱을 열면 항상 인증 → 메인 진입 순서가 유지됩니다.
비슷한 인증 방식 비교
방식 설명과 장단점
Face ID / Touch ID (현재) | 생체 인증 | 빠르고 편리, UX 자연스러움 | 기기 지원 필요, 실패 처리 필요 |
앱 비밀번호 입력 | 사용자 지정 암호 | 모든 기기 지원 | 관리 복잡, 유출 위험 |
비인증 상태 유지 | 인증 없음 | 구현 쉬움 | 보안 없음, 개인 정보 노출 |
느낀 점
생체인증은 생각보다 구현 자체는 간단하지만,
SwiftUI와 결합할 때 앱 흐름을 어떻게 설계할지가 훨씬 중요하다는 걸 느꼈습니다.
특히 인증 성공 여부에 따라 어떤 화면을 보여줄지 분기 처리하는 구조를
MVVM 기반 ViewModel을 통해 깔끔하게 분리해두는 것이
나중에 테스트, 확장, UI 변경 시에도 큰 도움이 될 거라 확신했습니다.
'iOS & SwiftUI' 카테고리의 다른 글
SwiftUI에서 감정 통계 뷰 설계 및 사용자 피드백 표시 방식 (1) | 2025.05.10 |
---|---|
SwiftUI에서 날짜 필터링 및 회고 리스트 정렬 구조 설계하기 (0) | 2025.05.10 |
SwiftUI에서 회고 데이터 모델 설계와 감정/내용 저장 방식 (2) | 2025.05.06 |
SwiftUI에서 작성/수정 화면을 분리하고 전환 흐름 구성하기 (2) | 2025.05.06 |
SwiftUI에서 감정 이모지 선택 UI 구현하기: HStack 기반 구조 (2) | 2025.05.05 |