관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] PropertyWrapper를 이용한 디버깅 테크닉 (#이벤트 로깅) 본문

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 
    }
}

* 전체 코드: https://github.com/JK0369/ExDebuggingProperty

Comments