Onboarding: 신입 사원이 조직 구성원이 되기 위해 필요한 지식, 기술, 행동을 교육하는 과정
앱에서 온보딩이라 하면 보통 최초로 실행했을 때 앱에 대한 정보 또는 사용 방법을 제공하기 위한 화면을 지칭합니다.
예를 들어,
게임이라면 처음 다루는 플레이어가 조작법에 익숙해질 수 있는 튜토리얼이 될 것이고,
헬스 케어라면 건강 앱에 대한 권한 허용과 정보 수집 및 이용에 대한 서명을 다룰 수 있겠죠?
SwiftUI에서 온보딩을 사용한다면 주로 AppStorage를 사용해요.
AppStorage: A property wrapper type that reflects a value from UserDefaults and invalidates a view on a change in value in that user default.
대충 UserDefaults라는 녀석의 값을 반영하는 프로퍼티 래퍼라는 것 같네요.
앱을 처음 시작하는 사람을 위한 온보딩을 만들어보겠습니다.
온보딩 여부를 확인하기 위해 Bool을 사용합니다.
struct ContentView: View {
@State var isOnboarding: Bool = false
var body: some View {
if isOnboarding { // MARK: Main
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Hello, world!")
}
.padding()
} //: Main
else { // MARK: Onboarding
Button {
isOnboarding = true
} label: {
Text("시작하기")
}
} //: Onboarding
}
}
하지만 State는 앱이 새로 실행될 때 저장되지 않기 때문에 이를 AppStorage로 바꿔줄게요.
@AppStorage()를 입력한 상태로 ⌃ + ␣ 를 눌러주면 Key 값으로 String을 받는 걸 확인할 수 있어요.
isOnboarding이라는 Key 값을 받는 AppStorage 프로퍼티와 변수를 선언해 보겠습니다.
struct ContentView: View {
@AppStorage("isOnboarding") var isOnboarding: Bool = false
var body: some View {
if isOnboarding { // MARK: Main
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Hello, world!")
}
.padding()
} //: Main
else { // MARK: Onboarding
Button {
isOnboarding = true
} label: {
Text("시작하기")
}
} //: Onboarding
}
}
조금 더 모듈화를 해볼게요.
온보딩 버튼을 따로 컴포넌트로 만들어준다. (⌘ + Left Click → Extract SubView)
struct ContentView: View {
@AppStorage("isOnboarding") var isOnboarding: Bool = false
var body: some View {
if isOnboarding { // MARK: Main
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Hello, world!")
}
.padding()
} //: Main
else { // MARK: Onboarding
ExtractedView()
} //: Onboarding
}
}
struct ExtractedView: View {
var body: some View {
Button {
isOnboarding = true
} label: {
Text("시작하기")
}
}
}
ExtractedView에도 isOnboarding을 추가하고, 따로 파일로 만들어줍시다.
struct ExtractedView: View {
@AppStorage("isOnboarding") var isOnboarding: Bool = false
var body: some View {
Button {
isOnboarding = true
} label: {
Text("시작하기")
}
}
}
마지막 작업
이건 선호도에 따라 갈릴 수 있다고 생각해요.
지금은 온보딩과 ContentView 밖에 없지만 프로젝트를 진행할 땐 ContentView에 다른 다양한 코드들이 추가되겠죠?
그래서 개인적으로 ContentView에 온보딩 분기가 있는 것보다 메인 앱에 있는 게 더 깔끔하다고 생각하는데 이에 대한 의견을 공유해 주세요!
struct OnboardingExampleApp: App {
@AppStorage("isOnboarding") var isOnboarding: Bool = false
var body: some Scene {
WindowGroup {
if isOnboarding { // MARK: ContentView
ContentView()
} //: ContentView
else { // MARK: Onboarding
ExtractedView()
} //: Onboarding
}
}
}
그렇게 나온 결과물
물론, HIG에 따르면 이상적으로 온보딩 없이 사용자가 경험해 보고 익히길 권장하지만, 그래도 애플 생태계에서 흔하게 접할 수 없거나, 사용자가 낯선 환경이라고 느낀다면 혼란을 겪기 전에 온보딩 경험을 제공하는 것도 좋다고 생각합니다.
'Swift' 카테고리의 다른 글
Vision: visionOS simulator (0) | 2023.08.22 |
---|---|
Vision: visionOS란? (0) | 2023.08.22 |
SwiftUI: map, compactMap, flatMap (0) | 2023.08.11 |
SwiftUI: Mask Design (0) | 2023.08.11 |
SwiftUI: BlendMode (0) | 2023.08.09 |