iOS 개발 기록

[Swift] Property wrapper 본문

Swift

[Swift] Property wrapper

택꽁이 2023. 2. 6. 13:19
728x90

PropertyWrapper

Available: iOS 13.0+
Date: 2022년 12월 27일
Tags: Swift

PropertyWrapper

  • 이미 정의된 property를 감싸 computed property로 만든 새로운 wrapper프로퍼티를 의미
  • stored property(didSet)이나 computed property(get, set)로 사용 가능
  • 프로퍼티에 로직을 연결해 볼리어 플레이트 코드와 재사용성을 높인다.

사용법

  • class, struct, enum 등 프로퍼티를 가질 수 있는 타입 앞에 붙여 사용
// 기본 코드 
struct Person { 
    private var _name: String = "" 
    var name: String { 
        get { self._name.uppercased()}
        set { self._name = newValue }
    }

    init(name: String) {
        self.name = name
    }
}

let person = Person(name: "abcd")
print(person.name) // ABCD
// PropertyWrapper 
struct Person { 
    @Upper var name: String
    init(name: String) {
        self.name = name
    }
}

@propertyWrapper 
struct Upper {
    private var value: String = ""
    var wrappedValue: String { 
        get { self.value }
        set { self.value = newValue.uppercased()}
    }

    init(wrappedValue initialValue: String) { 
        self.wrappedValue = initialValue               
    }
}

let person = Person(name: "abcd")
print(person.name) // ABCD

활용법

  • NUGU sample 앱을 보면 UserDefault에 맵핑해서 사용하고 있었다.
// Nugu SampleApp
@propertyWrapper
struct UserDefault<T> {
    let userDefaults: UserDefaults
    let key: String
    let defaultValue: T

    var wrappedValue: T {
        get {
            return userDefaults.object(forKey: key) as? T ?? defaultValue
        } set {
            if let value = newValue as? OptionalProtocol, value.isNil() {
                userDefaults.removeObject(forKey: key)
            } else {
                userDefaults.set(newValue, forKey: key)
            }
        }
    }
}

// 사용예
@UserDefault(userDefaults: .standard, key: "useNuguService", defaultValue: true)
static var useNuguService: Bool

ProjectedValue

  • propertyWrapper 내부의 다른 값을 정의하고, 해당 값에 접근 가능할 수 있는 기능
  • 접두사 $로 접근한다.
  • 꼭 이름이 propertyWrapper 여야 한다
@propertyWrapper 
struct Upper {
    private var value: String = ""
    var projectedValue: String { self.value }

      ... 
}

let person = Person(name: "abcd")
print(person.$name)     // ABCD

참고

https://github.com/nugu-developers/nugu-ios

[Swift] Property Wrapper

[iOS - swift] @propertyWrapper의 projectedValue 개념 ($ 접두사, 달러 접두사)

'Swift' 카테고리의 다른 글

[Swift] 정규표현식  (0) 2024.07.19
weak self, unowned self  (0) 2023.02.16
에러 처리  (0) 2022.10.24
Swift - 동기와 비동기(sync, async), 직렬과 동시(serial, concurrent)  (0) 2022.07.21
Swift - 옵셔널 (Optional)  (0) 2022.07.19