구조체와 Property wrapper를 통한 추상화

lyoodong·2023년 11월 20일

구조체와 Property wrapper를 통한 UserDefaults 추상화

  1. 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)
  1. 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) 입니다.")
  1. 타입 프로퍼티를 구조체로 전환해 재사용성 확보, 이때 제네릭 활용해 타입 유연성 증대
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)
}
  1. 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 추상화

  • diction 코드 개선
@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

}

0개의 댓글