본문 바로가기
iOS.Swift

[Swift] property wrapper 정의 및 사용법 예시

by 동동하다 2023. 11. 24.
반응형

propert wrapper는 Swift5.1에 추가된 개념으로 이름에서 말하든 property를 감싸서 새로운 property를 만드는 것을 말한다. 

그냥 이렇게만 들어보면 개념이 잘 안 잡히지만 Swift 를 사용하는 개발자라면 한 번씩 사용해 본 경험이 있을 것이다.

@State
@Published
@Binding

 

위와 같이 property 앞에 추가되는 것이 property wrapper이다. 

그럼 사용법 및 예시를 자세히 알아보자

 

사용법

우선 property wrapper를 사용하기 위해서는 local stored property 만 가능하다.

global property, computed property 에는 사용할 수 없다는 것을 명심하고 바로 예시를 보자

 

@propertyWrapper
struct Marked {
    var wrappedValue:String
}

 

property wrapper를 정의하기 위해서는 wrappedValue를 정의한 struct, class, enum를 만들고 이것이 property wrapper라는 것을 명시하는 @propertyWrapper를 써주면 된다.

 

위에 예시에서 Marked라는 propertyWrapper를 만들었지만, wrappedValue의 값이 세팅되고 호출될 때 아무런 액션이 없기에 이 propertyWrapper는 아무런 기능을 하지 못한다.

Marked는 비밀번호 등 민감한 정보를 숨겨서 보여주도록 하는 기능을 추가해 보자

@propertyWrapper
struct Marked {
    private var plain = ""
    
    var wrappedValue:  String  {
        set { self.plain = newValue }
        get {
            var result = ""
            for _ in 0 ..< self.plain.count {
                result = "*\(result)"
            }
            
            return result
        }
    }
    
    init(wrappedValue:String){
        self.wrappedValue = wrappedValue
    }
}

 

wrappedValue를 세팅할 때 내부적으로 정의된 plain라는 property에 값을 세팅하고, 호출할 때 plain에 정의된 string의 글자수만큼 * 표시를 해준다.

이 property wrapper를 사용하는 부분은 아래와 같다.

 

struct MarkedTest {
    @Marked var password:String = "PASSWORD"
    
    init() {
        print(password)		// ********
    }
}

 

projected Value

만약 Marked 된 string의 원문인 plain text를 사용해야 하는 경우에는 어떻게 해야 할까?

projectedValue를 이용해서 plain text 를 보여줄 수 있다.

 

@propertyWrapper
struct Marked {
    private var plain = ""
    
    var wrappedValue:  String  {
        set { self.plain = newValue }
        get {
            var result = ""
            for _ in 0 ..< self.plain.count {
                result = "*\(result)"
            }
            
            return result
        }
    }
    
    // projectedValue 추가
    var projectedValue: String{
        self.plain
    }
    
    init(wrappedValue:String){
        self.wrappedValue = wrappedValue
    }
}

 

위와 같이 projectedValue 를 추가하고 projectedValue 접근 시 plain text를 반환하도록 정의한다.

그리고 projectedValue에 접근하고 싶을 때는 $ 표시를 이용하면 된다. 기존에 wrappedValue 에 접근하던 property 앞에 $ 표시를 붙이면 projectedValue 에 접근할 수 있다.

 

struct MarkedTest {
    @Marked var password:String = "PASSWORD"
    
    init() {
        print(password)		// ********
        print($password)	// PASSWORD
    }
}
반응형

'iOS.Swift' 카테고리의 다른 글

[Swift] class 와 struct 의 차이  (0) 2023.11.15
iOS에서 Chrome 웹뷰 디버깅 하기  (0) 2023.10.24