NSUserDefaults에 대해 공부해보기로 하였다. 이것을 하는 이유는 현재 개발 중인 앱이 OnboardingScreen(소개 화면)이 있는데, 앱을 껐다가 다시 켜도 이 화면이 계속 나오기 때문에 이미 읽었다고 기억하고 다음 부터는 보여주지 않도록 하기 위해서이다. 단순히 flag를 통해 didFinishOnboarding 같은 곳에 표시를 해줬었는데, 이러한 경우 되기는 하지만 어플을 완전히 종료한다면 기억을 하지 못하였다.

그리고 이것을 왜 사용하는지 더 알아보니, 사용자 설정을 기억할 수 있었다. (로컬 알림 설정 여부, 음량 등) 또한, 앱이 꺼질 때는 값이 저장되지만 앱을 삭제한다면 모든 정보가 함께 사라지기 원할 경우에도 사용된다.

그래서 꼭 알아야 한다. 본격적으로 알아보도록 하자.

LocalState.swift

import Foundation

public class LocalState {
    private enum Keys: String {
        case hasOnboarded
    }
    
    public static var hasOnboarded: Bool {
        get {
            return UserDefaults.standard.bool(forKey: Keys.hasOnboarded.rawValue)
        }
        set(newValue) {
            UserDefaults.standard.set(newValue, forKey: Keys.hasOnboarded.rawValue)
            UserDefaults.standard.synchronize()
        }
    }
}

조금 전, 언급한 Onboarding 화면을 이미 유저가 보았는지 기억하기 위한 뼈대 코드이다.

enum은 keys를 나타낸다. 그리고 get을 통해 UserDefaults에 접근을 하여 Bool 타입인 hasOnboarded 정보를 가져오게 된다.

설정을 위한 set 부분을 보면 bool 타입으로 새로운 값을 전달하게 되는데, 전달된 값을 디스크에 기록하고 새 값을 기억하게 된다.

다음 줄의 synchronize는 모든 것이 동기화 되고 race condition(둘 이상의 입력 또는 조작의 타이밍이나 순서 등이 결과값에 영향을 줄 수 있는 상태)를 방지하게 된다. (Apple에 의하면 iOS 12부터는 NSUserDefaults를 쓸 때, synchronized가 더이상 필요하지 않다고 한다.(Sep.9th 2022))

이렇게 세팅은 끝나게 되었고, 실제로 어떻게 사용하는지 알아보자.

AppDelegate

extension AppDelegate: LoginViewControllerDelegate {
    func didLogin() {
        if LocalState.hasOnboarded {
            setRootViewController(dummyViewController)
        } else {
            setRootViewController(onboardingContainerViewController)
        }
    }
}

extension AppDelegate: OnboardingContainerViewControllerDelegate {
    func didFinishOnboarding() {
        LocalState.hasOnboarded = true
        setRootViewController(dummyViewController)
    }
}

사용하는 방법은 매우매우 심플하다. LocalState.hasOnboarded를 통해 접근하면 된다.

인터넷을 통해 찾아보니, 더욱 다양한 방법과 기능들이 있는 것 같았다. 차근차근 다른 것들을 구현하며, 더욱 딥하게 알아봐야겠다.

태그:

카테고리:

업데이트: