apple/SwiftUI & Combine

SwiftUI DynamicProperty

lgvv 2024. 8. 14. 22:18

SwiftUI DynamicProperty

 

뷰의 외부 속성을 업데이트하는 저장 프로퍼티에대한 인터페이스

 

DynamicProperty

 

 

view의 body를 다시 계산(recomputing)하기 전에 해당 속성값을 제공

 

 

  • 내부적으로 update() 메소드에 의해 기본 값을 업데이트.
  • 이 메소드는 필수이며 기본 구현이 제공됨. 이를 통해 저장 프로퍼티를 새로운 값으로 갱신.
  • 일반적으로 SwiftUI에서 @State와 같은 프로퍼티 래퍼가 사용될 때 뷰의 상태가 변하면 자동으로 호출되어 뷰의 상태를 최신으로 유지하는데 사용.

 

예제

내용을 FileManager에 실시간으로 저장하는 예제.

@AppStroage와 동일한 기능.

영상



@propertyWrapper
struct Document: DynamicProperty {
    @State private var value = ""
    
    private let url: URL
    
    var wrappedValue: String {
        get { value }
        nonmutating set {
            do {
                try newValue.write(to: url,
                                   atomically: true,
                                   encoding: .utf8)
                value = newValue
            } catch {
                print("파일 작성 실패")
            }
        }
    }
    
    var projectedValue: Binding<String> {
        Binding(
            get: { wrappedValue },
            set: { wrappedValue = $0 }
        )
    }
    
    init(_ filename: String) {
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        url = paths[0].appendingPathComponent(filename)

        let initialText = (try? String(contentsOf: url)) ?? ""
        _value = State(wrappedValue: initialText)
    }
}

struct DocumentView: View {
    @Document("chat") var document
    
    var body: some View {
        VStack {
            Text(document)
            
            Spacer()
            
            TextField("저장할 내용 입력", text: $document)
                .padding(20)
                .background(.blue.opacity(0.2))
        }
    }
}

#Preview {
    DocumentView()
}

 

 

@propertyWrapper를 사용하여 wrappedValue를 구현

projectedValue에 Binding을 통해 get - set을 사용하여 데이터 동적으로 처리되도록 반영

 

- nonmutating set으로 해야하는 이유

1. projectedValue가 struct 내부에 value를 변경하지 못함.

2. nonmutating으로 처리하여 구조체를 냅둔 채 @State로 선언된 value를 변화시킴.

nonmutating의 경우에는 아래 개념 참고.

https://rldd.tistory.com/626

 

 

 

(참고)
https://developer.apple.com/documentation/swiftui/dynamicproperty