나는 사용자의 회원 가입의 진행 상황에 따라서 처음 어플을 켰을 때 등장하는 화면을 달라지게 하고 싶다!
진행 상황 | 진입 시 표시되는 첫 화면 |
---|---|
첫 시작 | Onboarding View |
번호 인증 전 | Auth View |
번호 인증 후, 회원 가입 전 | SignUp View |
회원 가입 후 | Main View |
☄️ 목표: 사용자의 상황에 따라서, StartMdoe라는 enum을 통해서 분기 처리를 하고자 했다.
아래는 내가 생각한 SceneDelegate의 코드이다.
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
window?.windowScene = windowScene
// 흐음..수정필요
let startMode:StartMode = UserDefaults.standard....
var startViewController: UIViewController
switch startMode {
case .onBoarding:
startViewController = OnboardingViewController()
case .auth:
startViewController = AuthViewController()
case .signUp:
startViewController = SignUpViewController()
case .main:
startViewController = MainViewController()
}
window?.rootViewController = UINavigationController(rootViewController: startViewController)
window?.makeKeyAndVisible()
}
enum과 switch를 이용해서 이렇게 하고싶은데......
🐾 그럼 UserDefaults에 StartMode의 타입을 가진 변수를 저장해야 한다.
❗️하지만 UserDefaults에는 String, Int, Bool, Date의 데이터 타입만이 들어가 수 있어서 enum
은 넣을 수 없다.
🙋 그래서.. rawValue
를 활용해서 저장해 보았다.
enum StartMode: String {
case onBoarding
case auth
case signUp
case main
}
extension UserDefaults {
private enum UserDefaultsKeys: String {
case startMode
...
}
var startMode: String {
get { string(forKey: UserDefaultsKeys.startMode.rawValue) ?? StartMode.onBoarding.rawValue}
set { setValue(newValue, forKey: UserDefaultsKeys.startMode.rawValue)}
}
// 유저디폴트의 startMode에 StartMode.rawValue를 저장하기
UserDefaults.standard.startMode = StartMode.onBoarding.rawValue
이렇게 하면 enum
값을 이용하여 UserDefaults에 값을 저장할 수 있다.
하지만 따지고 보면,, sartMode는 enum SartMode: String
의 rawValue
, 즉 String이다.
⇢ 그래서 내가 원하는 것처럼, switch문을 통해서 첫 시작 화면을 분기하기 위해 switch문
을 사용하지 못한다.
오류가 나는 이유는 변수 startMode는 enum StartMdoe
가 아니라 String
타입이라는 것.
🐾 그렇다면어 어떻게 해주어야 할까?
🙋 Strig 타입
을 enum 타입
으로 바꾸어주는 과정이 필요하다.
enumName(rawValue: rawValue)
나의 코드에서는 ➣ let startMode = StartMode(rawValue: startModeString)
let startModeString = UserDefaults.standard.startMode
let startMode = StartMode(rawValue: startModeString)
var startViewController: UIViewController
switch startMode {
case .onBoarding:
startViewController = OnboardingViewController()
case .auth:
startViewController = AuthViewController()
case .signUp:
startViewController = SignUpViewController()
case .main:
startViewController = MainViewController()
case .none:
startViewController = OnboardingViewController()
}
case를 빠뜨렸다고 나온다. 다 썼는데..?
➣ Fix
를 누르면 case .none 이라고 해서, 기본 값이 추가된다.
우선 case .none:
에 대한 이벤트를 추가해 주면 에러는 사라진다.
let startModeString = UserDefaults.standard.startMode
let startMode = StartMode(rawValue: startModeString)
var startViewController: UIViewController
switch startMode {
case .onBoarding:
startViewController = OnboardingViewController()
case .auth:
startViewController = AuthViewController()
case .signUp:
startViewController = SignUpViewController()
case .main:
startViewController = MainViewController()
case .none:
startViewController = OnboardingViewController()
}
🐾 그런데, enum을 사용하면 이런 디폴트값을 주지 않아도 되는 것으로 알고 있었는데??
🙋 위의 코드에서 기본값에 대한 처리를 요구하는 이유는 내가 rawValue
를 이용해서 enum 타입을 만든 것에 있다.
swift문서를 살펴보면.. (🔗바로가기)
Initializing from a Raw Value
즉, rawValue로 초기화를 하는 경우에는,
👉 enumeration case
를 반환하거나,
👉 nil
을 반환한다.
이 때에는 .none
에 대한 처리를 해주어야 하는 것이다.❗️(대충 빨간옷입은 애기가 알아차린 짤)
🙋 switch문에서 하지 않고, StartMode(rawValue: rawValue)
를 만들면서 해 줄 수 있다.
let startMode = StartMode(rawValue: startModeString) ?? .onBoarding
요렇게 기본 값을 정해주면 된다.
그래서 enum값을 UserDefaults에 저장하고, switch문으로 분기처리를 하는 최종 코드는 다음과 같다.
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
window?.windowScene = windowScene
let startModeString = UserDefaults.standard.startMode
let startMode = StartMode(rawValue: startModeString) ?? .onBoarding
var startViewController: UIViewController
switch startMode {
case .onBoarding:
startViewController = OnboardingViewController()
case .auth:
startViewController = AuthViewController()
case .signUp:
startViewController = SignUpViewController()
case .main:
startViewController = MainViewController()
}
window?.rootViewController = UINavigationController(rootViewController: startViewController)
window?.makeKeyAndVisible()
}
🔖 참고