iOS 응용 (swift)
[iOS - swift] PropertyWrapper를 이용한 디버깅 테크닉 (#이벤트 로깅)
jake-kim
2023. 10. 7. 01:24
PropertyWrapper를 이용한 로깅
* propertyWrapper 개념은 이전 포스팅 글 참고
- propertyWrapper를 이용하면 사용하는쪽에서는 일반 property처럼 사용할 수 있지만, 내부적으로 wrapping하여 프로퍼티가 get되거나 set될때 다양한 처리가 가능
- set될때 로깅 스택에 쌓아놓는 방향으로하면 사용하는쪽에서는 단순히 프로퍼티에 값만 변경해주어도 자동으로 로깅되므로 쉽게 사용이 가능
propertyWrapper로 로깅하는 구조
- 기본적인 propertyWrapper 정의
@propertyWrapper
struct HistoryProperty<T> {
var _wrappedValue: T
var wrappedValue: T {
get { _wrappedValue }
set {
_wrappedValue = newValue
}
}
init(wrappedValue: T) {
self._wrappedValue = wrappedValue
}
}
- propertyWrapper 내부에 stack 배열을 선언
- 값이 set되는 시점에 stack에 append 처리
@propertyWrapper
struct HistoryProperty<T> {
private(set) var stack = [T]() // <-
var _wrappedValue: T
var wrappedValue: T {
get { _wrappedValue }
set {
stack.append(newValue) // <-
_wrappedValue = newValue
}
}
init(wrappedValue: T) {
self._wrappedValue = wrappedValue
stack.append(wrappedValue) // <-
}
}
- 사용하는쪽에서 로깅을 찍어볼 수 있어야 하므로 printStack() 메소드를 추가
// in struct HistoryProperty<T>...
func printStack() {
stack
.forEach { print($0, terminator: " ") }
}
- propertyWrapper 내부의 메소드에 접근하려면 projectedValue로 접근하게 해야하므로 projectedValue에서 self를 리턴하도록 하여 propertyWrapper 메소드 접근 가능하도록 인터페이스 열어주기
// in struct HistoryProperty<T>...
var projectedValue: Self {
self
}
- 사용하는쪽에서는 해당 프로퍼티.printStack()으로 로깅 확인이 가능
class ViewController: UIViewController {
@HistoryProperty
var personName = "jake"
override func viewDidLoad() {
super.viewDidLoad()
personName = "jong"
personName = "kim"
personName = "j"
$personName.printStack() // jake jong kim j
}
}