[iOS] Project - BuyOrNot
[iOS] propertyWrapper를 활용한 UserDefaults 캡슐화
ungQ
2024. 4. 28. 23:39
프로젝트를 진행하다보니, UserDefaults 값을 이곳 저곳 쓸일이 많았고 반복되는 코드들에 불편함을 느껴
@propertyWrapper 속성을 사용하여 코드의 간결함, 유지보수에 보탬이 되도록 개선해보려 합니다.
기존 방식
enum UserDefaultsKey: String {
case userId
case email
case password
case accessToken
case refreshToken
case nick
case profileImage
case autoLogin
var key: String {
return self.rawValue
}
}
UserDefaults.standard.set("user@example.com", forKey: UserDefaultsKey.email.key)
let email = UserDefaults.standard.string(forKey: UserDefaultsKey.email.key) ?? "error"
- 위와 같이 UserDefaults를 사용할 때마다 .standard .set .string 등의 코드가 추가적으로 필요합니다.
- @propertyWrapper 속성으로 UserDefaults 값들을 더 깔끔하고 간결하게 캡슐화하는 방법으로 개선해보았습니다.
@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.setValue(newValue, forKey: key)
}
}
}
@propertyWrapper 속성을 적용한 MyDefaults 구조체 생성
- get : UserDefaults.standard.object(forKey:)
- set : UserDefaults.standard.set(newValue, forKey:)
enum UserDefaultsManager {
enum Key: String {
case userId
case email
case password
case accessToken
case refreshToken
case nick
case profileImage
case autoLoginEnabled
}
@MyDefaults(key: Key.userId.rawValue, defaultValue: "")
static var userId: String
@MyDefaults(key: Key.email.rawValue, defaultValue: "이메일 없음")
static var email: String
@MyDefaults(key: Key.password.rawValue, defaultValue: "")
static var password: String
@MyDefaults(key: Key.accessToken.rawValue, defaultValue: "")
static var accessToken: String
@MyDefaults(key: Key.refreshToken.rawValue, defaultValue: "")
static var refreshToken: String
@MyDefaults(key: Key.nick.rawValue, defaultValue: "닉네임 없음")
static var nick: String
@MyDefaults(key: Key.profileImage.rawValue, defaultValue: "")
static var profileImage: String
@MyDefaults(key: Key.autoLoginEnabled.rawValue, defaultValue: false)
static var autoLoginEnabled: Bool
}
UserDefaultsManager 정의
- @Mydefaults propertyWrapper를 사용하여, 키와 값을 관리하는 UserDefaultsManager를 정의합니다.
개선된 코드 (주석: 기존 코드)
let myId = UserDefaultsManager.userId
// UserDefaults.standard.string(forKey: UserDefaultsKey.userId.key) ?? ""
HTTPHeader.authorization.rawValue: UserDefaultsManager.accessToken,
// UserDefaults.standard.string(forKey: UserDefaultsKey.accessToken.key) ?? "",
HTTPHeader.refresh.rawValue: UserDefaultsManager.refreshToken
// UserDefaults.standard.string(forKey: UserDefaultsKey.refreshToken.key) ?? ""
static let imageDownloadRequest = AnyModifier { request in
var requestBody = request
requestBody.setValue(UserDefaultsManager.accessToken,
// UserDefaults.standard.string(forKey: UserDefaultsKey.accessToken.key) ?? "",
forHTTPHeaderField: HTTPHeader.authorization.rawValue)
requestBody.setValue(APIKey.sesacKey.rawValue, forHTTPHeaderField: HTTPHeader.sesacKey.rawValue)
return requestBody
}
UserDefaultsManager.accessToken = accessTokenModel.accessToken
// UserDefaults.standard.set(accessTokenModel.accessToken, forKey: UserDefaultsKey.accessToken.key)
UserDefaultsManager.nick = loginModel.nick
UserDefaultsManager.userId = loginModel.user_id
UserDefaultsManager.accessToken = loginModel.accessToken
UserDefaultsManager.refreshToken = loginModel.refreshToken
// UserDefaults.standard.set(loginModel.nick, forKey: UserDefaultsKey.nick.key)
// UserDefaults.standard.set(loginModel.user_id, forKey: UserDefaultsKey.userId.key)
// UserDefaults.standard.set(loginModel.accessToken, forKey: UserDefaultsKey.accessToken.key)
// UserDefaults.standard.set(loginModel.refreshToken, forKey: UserDefaultsKey.refreshToken.key)
결론
- UserDefaults를 캡슐화하여, 상용구 코드를 줄이고 가독성을 높였습니다.
- UserDefaults 값을 한 곳에서 관리하여 유지보수를 향상시켰습니다.