구조체와 Property wrapper를 통한 UserDefaults 추상화
- enum을 통해 Key값 열거
enum UserKey: String {
case email, nickname, phone
}
UserDefaults.standard.set("a@a.com", forKey: UserKey.email.rawValue)
UserDefaults.standard.set("닉네임", forKey: UserKey.nickname.rawValue)
UserDefaults.standard.set("2345", forKey: UserKey.phone.rawValue)
UserDefaults.standard.string(forKey: UserKey.email.rawValue)
UserDefaults.standard.string(forKey: UserKey.nickname.rawValue)
UserDefaults.standard.string(forKey: UserKey.phone.rawValue)
- UserDefaultsManager 생성, 타입 프로퍼티를 통해 코드 개선
- 이때 컴파일 최적화를 위해 내부에서 Key 선언
enum UserDefaultsManager {
enum Key: String {
case email
case nickname
case phone
}
static var email: String {
get {
UserDefaults.standard.string(forKey: Key.email.rawValue) ?? "이메일 없음"
}
set {
UserDefaults.standard.set(newValue, forKey: Key.email.rawValue)
}
}
static var nickname: String {
get {
UserDefaults.standard.string(forKey: Key.nickname.rawValue) ?? "닉네임 없음"
}
set {
UserDefaults.standard.set(newValue, forKey: Key.nickname.rawValue)
}
}
static var phone: String {
get {
UserDefaults.standard.string(forKey: Key.phone.rawValue) ?? "전화번호 없음"
}
set {
UserDefaults.standard.set(newValue, forKey: Key.phone.rawValue)
}
}
}
UserDefaultsManager.email = "3@gmail.com"
print("이메일 \(UserDefaultsManager.email) 입니다.")
- 타입 프로퍼티를 구조체로 전환해 재사용성 확보, 이때 제네릭 활용해 타입 유연성 증대
struct Defaults<T> {
let key: String
let defaultsValue: T
var value: T {
get {
UserDefaults.standard.object(forKey: key) as? T ?? defaultsValue
}
set {
UserDefaults.standard.set(newValue, forKey: key)
}
}
}
enum UserDefaultsManager {
enum Key: String {
case email
case nickname
case phone
}
static var email = Defaults(key: Key.email.rawValue, defaultsValue: "이메일 없음")
static var nickname = Defaults(key: Key.nickname.rawValue, defaultsValue: "닉네임 없음")
static var phone = Defaults(key: Key.phone.rawValue, defaultsValue: 1234)
}
- Property wrapper를 통해 접근성 향상
→ 기존 UserDefaultsManager.email.value
→ 개선 UserDefaultsManager.email
@propertyWrapper
struct Defaults<T> {
let key: String
let defaultsValue: T
var wrappedValue: T {
get {
UserDefaults.standard.object(forKey: key) as? T ?? defaultsValue
}
set {
UserDefaults.standard.set(newValue, forKey: key)
}
}
}
enum UserDefaultsManager {
enum Key: String {
case email
case nickname
case phone
}
@Defaults(key: Key.email.rawValue, defaultsValue: "이메일 없음")
static var email
@Defaults(key: Key.nickname.rawValue, defaultsValue: "nickname 없음")
static var nickname
@Defaults(key: Key.phone.rawValue, defaultsValue: 1234)
static var phone
}
구조체와 Property wrapper를 통한 SortManger 추상화
@propertyWrapper
struct SortTarget<T: Object> {
private let repo = CRUDManager.shared
private let keyPath: String
private let ascending: Bool
init(keyPath: String, ascending: Bool) {
self.keyPath = keyPath
self.ascending = ascending
}
var wrappedValue: Results<T> {
return repo.read(object: T.self).sorted(byKeyPath: keyPath, ascending: ascending)
}
}
struct SortManger<T: Object> {
enum KeyPath: String {
case averageLevel
case interviewDate
}
@SortTarget<T>(keyPath: KeyPath.averageLevel.rawValue, ascending: false)
var resultByLevel
@SortTarget<T>(keyPath: KeyPath.interviewDate.rawValue, ascending: false)
var resultByNew
@SortTarget<T>(keyPath: KeyPath.interviewDate.rawValue, ascending: true)
var resultByOld
}