이모저모/Swift

UserDefaults with propertyWrapper

ARpple 2023. 11. 30. 14:35
💡 사용자가 생성한 UserDefaults와 인스턴스를 propertyWrapper로 한 번에 접근하기

사용 예시

struct Hello{
    @DefaultsState(path: \.groupShared, \.hello) var groupHello
    @DefaultsState(path: \.standard, \.hello) var standardHello
}

대략적인 구조

  1. 계산 프로퍼티로 접근 가능한 싱글톤 매개체 → UserDefaultsGroup
  2. UserDefaults에 커스텀 UserDefaults 만들기
  3. UserDefaults에 사용할 키-값 구성하기
  4. 프로퍼티 래퍼로 위 UserDefaultsGroup에 존재하는 UserDefaults 접근 후, 해당 UserDefaults 내부의 아이템 접근

1. 계산 프로퍼티로 접근 가능한 싱글톤 매개체

struct UserDefaultsGroup{
    static let shared = UserDefaultsGroup()
    private init(){}
        // UserDefaults.standard는 기본으로 존재함
    var standard:UserDefaults{UserDefaults.standard}
    var groupShared:UserDefaults{ UserDefaults.groupShared }

}

2. UserDefaults에 커스텀 UserDefaults 만들기

extension UserDefaults{
    // 공용 UserDefaults 만들기
    static var groupShared: UserDefaults{
        let appGroupID = "group.orderbook"
        return UserDefaults(suiteName: appGroupID)!
    }
}

3. UserDefaults에 사용할 키-값 구성하기

extension UserDefaults{
    var hello:Int{
        get{ self.integer(forKey: "hello") }
        set{self.set(newValue,forKey: "hello")}
    }
    var Market:String{
        get{self.string(forKey: "Market") ?? "No Market"}
        set{self.set(newValue,forKey: "Market")}
    }
}

4. 프로퍼티 래퍼로 위 UserDefaultsGroup에 존재하는 UserDefaults 접근 후, 해당 UserDefaults 내부의 아이템 접근

@propertyWrapper
struct DefaultsState<Value>{
    private var path: KeyPath<UserDefaultsGroup,UserDefaults>
    private var item: ReferenceWritableKeyPath<UserDefaults,Value>
    var wrappedValue: Value{
        get{
            UserDefaultsGroup.shared[keyPath: path][keyPath: item]
        }
        set{
            UserDefaultsGroup.shared[keyPath: path][keyPath: item] = newValue
        }
    }
    init(_ item: ReferenceWritableKeyPath<UserDefaults, Value>){
        self.init(path: \.standard,item)
    }
    init(path: KeyPath<UserDefaultsGroup, UserDefaults>,_ item: ReferenceWritableKeyPath<UserDefaults, Value>) {
        self.path = path
        self.item = item
    }
}

전체 코드

UserDefaultsGroup.swift
0.00MB