[새싹 iOS] 18주차_UserDefaults 추상화

임승섭·2023년 11월 18일
0

새싹 iOS

목록 보기
34/45

0. Basic

일반적인 UserDefualts 사용 방법

enum Key: String {
	case email, nickname, phone
}

// set
UserDefaults.standard.set("0@naver.com", forKey: Key.email.rawValue)
UserDefaults.standard.set("보리밥", forKey: Key.nickname.rawValue)
UserDefaults.standard.set("010-1234-1234", forKey: Key.phone.rawValue)

// get
let email = UserDefaults.standart.string(forKey: Key.email.rawValue)
let nickname = UserDefaults.standart.string(forKey: Key.nickname.rawValue)
let phone = UserDefaults.standart.string(forKey: Key.phone.rawValue)

1. enum UserDefaultsManager

UserDefault에 직접 접근하지 않고,
열거형 UserDefaultsManager를 통해 접근한다

enum UserDefaultsManager {

	// 컴파일 최적화 측면 - enum 내부에 선언한다
    enum Key: String {
    	case email, nickname, phone
    }
    
    // 1. email 
    static var email: String {
    	get {
        	UserDefaults.standard.string(forKey: Key.email.rawValue) ?? "No Email"
        }
        set {
        	UserDefaults.standard.set(newValue, forKey: Key.email.rawValue)
        }
    }
	
    // 2. nickname
    static var nickname: String {
    	get {
        	UserDefaults.standard.string(forKey: Key.nickname.rawValue) ?? "No Nickname"
        }
        set {
        	UserDefaults.standard.set(newValue, forKey: Key.nickname.rawValue)
        }
    }

	// 3. phone
    static var phone: String {
    	get {
        	UserDefaults.standard.string(forKey: Key.phone.rawValue) ?? "No Phone"
        }
        set {
        	UserDefaults.standard.set(newValue, forKey: Key.phone.rawValue)
        }
    }
}

/* ===== 사용 ===== */
UserDefaultsManager.email = "1@naver.com"
UserDefaultsManager.nickname = "보리보리밥"
UserDefaultsManager.phone = "010-1234-1234"

let email = UserDefaultsManager.email
let nickname = UserDefaultsManager.nickname
let phone = UserDefaultsManager.phone

2. struct MyDefaults

구조체 MyDefaults 로 한 번 더 감싼다

struct MyDefaults {
	let key: String 
    let defaultValue: String 
    
    var myValue: String {
    	get {
        	UserDefaults.standard.string(forKey: key) ?? defaultValue
        }
        set {
        	UserDefaults.standard.set(newValue, forKey: key)
        }
    }
}


enum UserDefaultsManager {

	enum Key: String {
    	case email, nickname, phone
    }
    
    static var email = MyDefaults(key: Key.email.rawValue, defaultValue: "No Email")
    static var nickname = MyDefaults(key: Key.nickname.rawValue, defaultValue: "No Nickname")
    static var phone = MyDefaults(key: Key.phone.rawValue, defaultValue: "No Phone")
}

/* ===== 사용 ===== */
UserDefaultsManager.email.myValue = "2@naver.com"
let email = UserDefaultsManager.email.myValue

2.5 struct MyDefaults + Generic

위 구조체 형식으로 만들면, 결국 myValue 타입이 달라질 때마다 또 다시 연산 프로퍼티를 여러 개 만들어야 한다.
이를 해결하기 위해 Generic 을 활용한다.

struct MyDefaults<T> {
	let key: String 
    let defaultValue: T
    
    let myValue: T {
    	get {
        	UserDefaults.standard.object(forKey: key) as? T ?? defaultValue
        }
        set {
        	UserDefaults.standard.set(newValue, forKey: key)
        }
    }
}


3. Property Wrapper

구조체 MyDefaults 에 대해 propertyWrapper의 역할을 하도록 한다.
기존에 myValue로 선언한 프로퍼티를 wrappedValue 로 교체함으로써 사용 시 코드를 더 줄일 수 있게 된다

@propertyWrapper
struct MyDefaults<T> {
	let key: String 
    let defaultValue: T
    
    var wrappedValue: T {
    	get {
        	UserDefaults.standard.object(forKey: key) as? T ?? defaultValue
        }
        set {
        	UserDefaults.standard.set(newValue, forKey: key)
        }
    }
}

enum UserDefaultsManager {
	
    enum Key: String {
    	case email, nickname, phone
    }
    
    @MyDefaults(key: Key.email.rawValue, defaultValue: "No Email")
    static var email

    @MyDefaults(key: Key.nickname.rawValue, defaultValue: "No Nickname")
    static var nickname
    
    @MyDefaults(key: Key.phone.rawValue, defaultValue: "No Phone")
    static var phone
}


/* ===== 사용 ===== */
UserDefaultsManager.email = "3@naver.com"
let email = UserDefaultsManager.email.myValue

    

0개의 댓글