Search

Swift - Property Wrapper / Projected Value

Tag
정보공유
Tech
Swift
날짜
2023/10/12
작성자
이창준
해결

Property Wrapper

SwiftUI 에서 @ObservedObject@State … 으로 만나게 되는..!
보일러플레이트 코드를 줄이기 위해 사용
Property Wrapper 사용 안했을 때 코드
struct House { private var width = 0 var size: Int { get { return width } set { width = pow(newValue, 2) } } } struct KoreaHouse { private var _apartment = House() private var _villa = House() var apartmentSize: Int { get { return _apartment.size } set { _apartment.size = newValue } } var villaSize: Int { get { return _villa.size } set { _villa.size = newValue } } }
Swift
복사
⇒ KoreaHouse 구조체 내에서 각 프로퍼티에서 매번 동일한 보일러 플레이트 코드를 작성
Property Wrapper 사용
@propertyWrapper struct House { private var width = 0 var size: Int { get { return width } set { width = pow(newValue, 2) } } } struct KoreaHouse { @House var apartment: Int @House var villa: Int } var koreaHouse = KoreaHouse() koreaHouse.apartment = 20 koreaHouse.villa = 30 print(koreaHouse.apartment, koreaHouse.villa) // 400, 900
Swift
복사
Property Wrapper 사용 + 생성자 버전
@propertyWrapper struct House { private var width = 0 var size: Int { get { return width } set { width = pow(newValue, 2) } } init(size: Int) { widht = pow(newValue, 2) } } struct KoreaHouse { @House var apartment: Int = 20 @House var villa: Int = 30 } var koreaHouse = KoreaHouse() print(koreaHouse.apartment, koreaHouse.villa) // 400, 900
Swift
복사

Projected Value

property wrapper가 저장하기 전에 값을 조정(adjust) 했는 지 알려줄 수 있음
@propertyWrapper struct SmallNumber { private var number: Int private(set) var projectedValue: Bool var wrappedValue: Int { get { return number } set { if newValue > 12 { number = 12 projectedValue = true } else { number = newValue projectedValue = false } } } init() { self.number = 0 self.projectedValue = false } }
Swift
복사
struct SomeStructure { @SmallNumber var someNumber: Int } var someStructure = SomeStructure() someStructure.someNumber = 4 print(someStructure.$someNumber) // Prints "false" someStructure.someNumber = 55 print(someStructure.$someNumber) // Prints "true"
Swift
복사

UserDefault 에 적용

Ex)

@propertyWrapper struct ImageString { private var image: String = "" private var fileExtension: String? private let defaultExtension = ".png" var wrappedValue: String { get { self.image + (self.fileExtension ?? defaultExtension) } set { self.image = newValue } } init(wrappedValue initialValue: String, fileExtension: String? = nil) { self.image = initialValue self.fileExtension = fileExtension ?? defaultExtension } } struct UserProfile { @ImageString var profileImage: String = "" @ImageString(fileExtension: ".jpg") var IDImage: String = "" } let userProfile = UserProfile(profileImage: "phang", IDImage: "leechangjun") print(userProfile.profileImage) print(userProfile.IDImage)
Swift
복사