Swift

propertyWrapper로 UserDefaults 관리

Phililip 2024. 5. 11.
728x90

안녕하세요.

 

propertyWrapper를 사용하면 UserDefaults 데이터 읽기/쓰기를 쉽게 하는 방법이 있어서 공유드리려구 해요.

 


프로젝트에 UserDefaultsWrapper라는 propertyWrapper를 추가해주세요. (당연히 이름은 마음대로 하셔도 됩니다.)

 

enum UserDefaultsKey: String {
// UserDefaults Dictionary에 저장할 데이터의 key
case userId
case loginTime
case profile = "com.my.company.profile"
}
@propertyWrapper
struct UserDefaultsWrapper<T: Codable> {
private let key: UserDefaultsKey
private let defaultValue: T?
private let standard: UserDefaults = UserDefaults.standard
init(key: UserDefaultsKey, defaultValue: T? = nil) {
self.key = key
self.defaultValue = defaultValue
}
var wrappedValue: T? {
get {
guard let data = self.standard.object(forKey: key.rawValue) as? Data else { return defaultValue }
let session = try? JSONDecoder().decode(T.self, from: data)
return session ?? defaultValue
}
set {
let data = try? JSONEncoder().encode(newValue)
self.standard.set(data, forKey: self.key.rawValue)
}
}
}

 

그 다음 UserDefaultsManager 라는 구조체를 만들고 UserDefaultsWrapper로 선언된 프로퍼티를 추가합니다.

 

struct UserDefaultsManager {
@UserDefaultsWrapper(key: .userId)
static var userId: String?
@UserDefaultsWrapper(key: .loginTime)
static var loginTime: Int?
@UserDefaultsWrapper(key: .profile)
static var profile: Profile?
}

 

UserDefaults에서 값을 읽거나 써야 할 땐 그냥 UserDefaultsManager의 stored property를 사용하면 됩니다.

(당연히 primitive type 뿐만 아니라 구조체도 가능해요!)

 

class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction private func onClickLogin(_ sender: Any) {
UserDefaultsManager.userId = "user1"
UserDefaultsManager.loginTime = Int(Date.now.timeIntervalSince1970)
UserDefaultsManager.profile = Profile(
name: "Philip",
age: 49,
location: .init(latitude: 100, longitude: 200)
)
}
@IBAction private func onClickLoadInfo(_ sender: Any) {
print(UserDefaultsManager.userId ?? "nil")
print(UserDefaultsManager.loginTime ?? 0)
print(UserDefaultsManager.profile ?? "nil")
}
}
struct Profile: Codable {
let name: String
let age: Int
let location: Location
struct Location: Codable {
let latitude: Double
let longitude: Double
}
}

 


이번 글은 여기서 마무리.

 

 

 

반응형

'Swift' 카테고리의 다른 글

@propertywrapper  (0) 2024.06.07
protocol initializer가 클래스에서 required로 정의되어야 하는 이유  (0) 2024.05.12
@discardableResult  (0) 2024.01.28
KeyValuePairs  (0) 2024.01.28
Memory Safety  (1) 2024.01.25