iOS) UserDefaults, switch, enum 으로 시작화면 분기처리 하기

minin·2022년 1월 22일
0

Swift연습장

목록 보기
8/11
post-thumbnail

iOS) UserDefaults, switch, enum 으로 시작화면 분기처리 하기

나는 사용자의 회원 가입의 진행 상황에 따라서 처음 어플을 켰을 때 등장하는 화면을 달라지게 하고 싶다!

진행 상황진입 시 표시되는 첫 화면
첫 시작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: StringrawValue, 즉 String이다.

⇢ 그래서 내가 원하는 것처럼, switch문을 통해서 첫 시작 화면을 분기하기 위해 switch문을 사용하지 못한다.

오류가 나는 이유는 변수 startMode는 enum StartMdoe가 아니라 String 타입이라는 것.

🐾 그렇다면어 어떻게 해주어야 할까?

🙋 Strig 타입enum 타입으로 바꾸어주는 과정이 필요하다.


어떻게 바꾸어주냐면, rawValue를 이용하면 됨.

enumName(rawValue: rawValue)

나의 코드에서는 ➣ let startMode = StartMode(rawValue: startModeString)


그런데 아래처럼 enum타입으로 변환을 해 주고 나면, 오류가 뜬다.
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을 반환한다.


우리가 코드에서 입력하는 String이 기존에 선언되어 있는 rawValue에 없을 수도 있기 때문에!

이 때에는 .none에 대한 처리를 해주어야 하는 것이다.❗️(대충 빨간옷입은 애기가 알아차린 짤)


🐾 결국 `nil`에 대한 처리를 해 주는 것인데, 조금 더 간단하게 쓸 수는 없을까?

🙋 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()
        
}

🔖 참고

profile
🍫 iOS 🍫 Swift

0개의 댓글