[SwiftUI] ObservableObject, ObservedObject, Published

2024. 10. 7. 09:49ยท๐ŸŽ Dev/SwiftUI

 

 

 

 

ํšŒ์‚ฌ์—์„œ SwiftUI๋กœ ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ์ง€๋งŒ, ํšŒ์‚ฌ ํ”„๋กœ์ ํŠธ ๊ธฐ๋ฐ˜์ธ UIKit์˜ ๊ทธ๋Š˜์—์„œ ๋ฒ—์–ด๋‚˜์ง€ ๋ชป ํ•ด์„œ ์–ธ์ œ๋‚˜ ๋ฐ˜์ชฝ์งœ๋ฆฌ SwiftUI๋กœ ์ž‘์—…ํ•˜๋Š” ๊ธฐ๋ถ„์ด ๋“ค์—ˆ๋‹ค. Property Wrapper๋ฅผ ์ž‘์—… ์ดˆ๊ธฐ์— ํšŒ์‚ฌ ์ปจํ”Œ๋ฃจ์–ธ์Šค์— ์ •๋ฆฌํ•˜๊ณ , ๊ทธ ๊ธ€์„ ๋‹ค์‹œ ์ด ๋ธ”๋กœ๊ทธ์— ์ ๊ธฐ๋„ ํ–ˆ๋Š”๋ฐ ๊ทธ๋• ํšŒ์‚ฌ์—์„œ ๊ฒ€์ƒ‰ํ•ด๋„ ๋ญ๊ฐ€ ๋ญ”์ง€ ๋ชฐ๋ผ์„œ ์ •์˜๋ณด๋‹ค๋„ ๋œป์„ ์ฐพ์•„๋ณธ ๋А๋‚Œ์ด ๊ฐ•ํ–ˆ๋‹ค. ์‹ค์ œ๋กœ ํšŒ์‚ฌ ํ”„๋กœ์ ํŠธ์—์„œ ํ•ด๋‹น wrapper๋“ค์„ ๋‹ค ํ™œ์šฉํ•˜์ง€ ๋ชป ํ•˜๊ธฐ๋„ ํ–ˆ๊ณ .

 

๊ทธ๋ž˜์„œ ๋‹ค์‹œ ์ฐจ๊ทผ์ฐจ๊ทผ ํ•˜๋‚˜์”ฉ ๊ฐ„๋‹จํžˆ ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ์งœ๋ณด๋ฉฐ ๊ณต๋ถ€ํ•ด๋ณด๊ณ  ์ •๋ฆฌํ•˜๊ณ ์ž ํ•œ๋‹ค.

 

์ฐธ๊ณ ๋กœ, wrapper ์ •๋ฆฌํ–ˆ๋˜ ๊ฒŒ์‹œ๊ธ€์„ ์•„๋ž˜ ๋งํฌ์˜ ๊ธ€์ด๋‹ค. ๊ฑฐ์ฐฝํ•œ ์ด์ •๋ฆฌ๋ž€ ํƒ€์ดํ‹€๊ณผ ๋‹ฌ๋ฆฌ ์ •๋ง ์ •์˜ ์˜์ฃผ๋กœ ์ •๋ฆฌ๋œ ๊ธ€์ด๋‹ค.

 

https://calliek.tistory.com/54#%C2%A0-8

 

[SwiftUI] Property Wrapper ์ด์ •๋ฆฌ

PropertyWrapper์ •์˜Swift 5.1 ๋ฒ„์ „๋ถ€ํ„ฐ ๋„์ž…๋œ ๋ฌธ๋ฒ•์ •์˜๋œ property๊ฐ€ ์žˆ์„ ๋•Œ ํ•ด๋‹น property๋ฅผ ๊ฐ์‹ธ์„œ ํŠน๋ณ„ํ•œ ํƒ€์ž…์œผ๋กœ ๋งŒ๋“ค์–ด์ค€๋‹ค.ํ”„๋กœํผํ‹ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ์ฝ”๋“œ์™€ ํ”„๋กœํผํ‹ฐ๋ฅผ ์„ ์–ธํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๊ทธ

calliek.tistory.com

 

 

 


 

 

์ด ํฌ์ŠคํŠธ์˜ ์ฃผ์ œ์ธ ObservableObject, ObservaedObject, Published๋Š” ๋ชจ๋‘ Combine์— ์†ํ•ด์žˆ๋‹ค.

Combine์€ rxSwift์ฒ˜๋Ÿผ ๋น„๋™๊ธฐ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์• ํ”Œ์ด ๋งŒ๋“  ํ”„๋ ˆ์ž„์›Œํฌ๋‹ค.

 

๊ทธ๋Ÿฐ๋ฐ ๊ฐ‘์ž๊ธฐ ์ปด๋ฐ”์ธ์„ ์™œ ์—ฌ๊ธฐ์„œ ์“ฐ๋Š”์ง€์— ๋Œ€ํ•ด ์˜๋ฌธ์ด ๋“ค ์ˆ˜๋„ ์žˆ๋Š”๋ฐ, state - binding์€ ์ƒ์œ„-ํ•˜์œ„๋ทฐ๊ฐ€ ๋ช…ํ™•ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์ˆ˜์˜ ๋ทฐ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ์—” ์ ํ•ฉํ•˜์ง€ ์•Š๋‹ค. ์™ธ๋ถ€์— ์„ ์–ธ ๋œ ๊ฐ’์„ ๊ด€์ฐฐํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ์—์„  ์ด๋ฒคํŠธ ๋ณ€ํ™”๋ฅผ ๊ด€์ฐฐํ•˜๋Š” observableObject์™€ observedObject ์“ฐ๋Š” ๊ฒŒ ์ ํ•ฉํ•˜๋‹ค.

 

 

 

 

 

 

ObservableObject

- ObservableObject๋Š” ๊ฐ์ฒด๊ฐ€ ๋ณ€๊ฒฝ ๋˜๊ธฐ ์ „์— ๋ฐฉ์ถœํ•˜๋Š” ํผ๋ธ”๋ฆฌ์…”๋ฅผ ๊ฐ€์ง„ ๊ฐ์ฒด๋‹ค.

- ๋ณ€ํ™”๋ฅผ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด๋กœ, ObservableObject๋ฅผ ์‚ฌ์šฉํ•œ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ด€์ฐฐํ•˜๊ณ  ์žˆ๋‹ค๊ฐ€ ํ”„๋กœํผํ‹ฐ์˜ ๋ณ€ํ™”๋ฅผ ๊ฐ์ง€ํ•˜๋ฉด ๋ทฐ๋ฅผ ๋‹ค์‹œ ๊ทธ๋ฆฌ๋ฉฐ ์—…๋ฐ์ดํŠธ ํ•ด์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

- "์–˜ ๊ฐ’ ๋ฐ”๋€Œ์—ˆ๋„ค, ์—…๋ฐ์ดํŠธ ์ง„ํ–‰ ์‹œ์ผœ!" ํ•˜๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

 

 

Published

- Published๋Š” ํด๋ž˜์Šค ๋‚ด๋ถ€ ๊ฐ์ฒด์˜ ๋ณ€ํ™”๋ฅผ ๊ฐ์ง€ํ–ˆ์„ ๋•Œ ์ž๋™์œผ๋กœ ๋ทฐ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์•Œ๋ฆฌ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

- ObservableObject ํด๋ž˜์Šค ๋‚ด๋ถ€์— ์„ ์–ธ ๋˜์–ด ์žˆ์„ ๋•Œ, willSet ์—ญํ• ์„ ํ•˜๋Š” objectWillChange ํผ๋ธ”๋ฆฌ์…”๋ฅผ ์ž๋™์œผ๋กœ ํ˜ธ์ถœํ•ด์„œ published๋กœ ์„ ์–ธ ๋œ ์†์„ฑ์˜ ๋ณ€ํ™”๋ฅผ ๊ฐ์ง€ ํ›„ ์—…๋ฐ์ดํŠธํ•˜๋„๋ก ํ•œ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ๋กœ ObservableObject์™€ ํ•จ๊ป˜ ์“ฐ์ธ๋‹ค.

- "๋‚˜ ๊ฐ’ ๋ฐ”๋€Œ์—ˆ์–ด, ์—…๋ฐ์ดํŠธ ํ•ด์•ผํ•ด!"ํ•˜๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

 

 

์‚ฌ์šฉ ์˜ˆ์‹œ

class UserSettings: ObservableObject {
  @Published var username = "Anonymous"
  @Published var count = 0
  @Published var isOn = false
}

 

 

1. ๊ณต์‹๋ฌธ์„œ์—๋„ ๋”ฐ๋กœ ๊ฐ•์กฐ๋˜์–ด ์žˆ๋Š” ๋ถ€๋ถ„์ธ๋ฐ, ObservableObject์™€ Published๋Š” class ๋‚ด์—์„œ๋งŒ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.

2. ์œ ์ €์™€ ๊ด€๋ จ๋œ ๊ฐ’์„ ๊ด€์ฐฐํ•  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— UserSettings๋ผ๋Š” ObservableObject ํด๋ž˜์Šค๋ฅผ ์„ ์–ธํ•˜๊ณ , ๊ทธ ์•ˆ์— ๊ด€์ฐฐํ•˜๊ณ  ์‹ถ์€ ๊ฐ’๋“ค์„ username, count, isOn ํ”„๋กœํผํ‹ฐ๋กœ Published ์„ ์–ธํ–ˆ๋‹ค.

3. Published๋กœ ์„ ์–ธํ•œ username, count, isOn์˜ ๊ฐ’์— ๋ณ€ํ™”๊ฐ€ ์ƒ๊ธฐ๋Š”์ง€ ๊ด€์ฐฐํ•œ๋‹ค.

 

 

ObservedObject

- ObservedObject๋Š” ๋ทฐ ์™ธ๋ถ€์—์„œ ์ƒ์„ฑ๋œ ๊ฐ์ฒด ์ƒํƒœ๋ฅผ ๊ตฌ๋…ํ•˜๊ณ , ์ƒํƒœ๊ฐ€ ๋ณ€ํ–ˆ์„ ๋•Œ๋งˆ๋‹ค UI๋ฅผ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.

- "๊ด€์ฐฐ ์ค‘์ด๋˜ ๋ฐ”๋€ ์•  ์—…๋ฐ์ดํŠธ ํ•จ!" ํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

 

 

์‚ฌ์šฉ ์˜ˆ์‹œ

struct PracticeObservableObject: View {
  
  @ObservedObject var settings = UserSettings()
  
    var body: some View {
      
      VStack {
        
        // MARK: - Change Name
        Text("Hello, \(settings.username)")
        Button(action: {
          settings.username = "New guy"
        }, label: {
          Text("Change Username")
            .labelStyle(.titleOnly)
        })
        
        // MARK: - Change Count
        Text("count: \(settings.count)")
        Button("Add Count") {
          settings.count += 1
        }
        
        // MARK: - Change Value
        Toggle("On", isOn: $settings.isOn)
          .padding(.horizontal, 150)
        Button("Make it On") {
          settings.isOn.toggle()
        }
      }
      
    }
}

 

4. PracticeObservableObject ๋ทฐ์— ๋ทฐ ์™ธ๋ถ€์—์„œ ์ „๋‹ฌ ๋ฐ›๋Š” UserSettings ๊ฐ์ฒด๋ฅผ ObservedObject๋กœ ์ƒ์„ฑํ•ด์„œ, ํ•ด๋‹น ๊ฐ’์„ ๊ตฌ๋… ๋ฐ ๋ณ€ํ™” ๊ด€์ฐฐ ํ•œ๋‹ค.

5. ๋ฒ„ํŠผ ์•ก์…˜์— ๋”ฐ๋ผ ๊ฐ’์ด ๋ณ€ํ™”ํ•˜๋ฉด, ๋ทฐ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค.

 

 

 

์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ

 

 

 

 

 

 

 

 


 

References

https://developer.apple.com/documentation/Combine/ObservableObject

 

ObservableObject | Apple Developer Documentation

A type of object with a publisher that emits before the object has changed.

developer.apple.com

 

https://developer.apple.com/documentation/swiftui/observedobject

 

ObservedObject | Apple Developer Documentation

A property wrapper type that subscribes to an observable object and invalidates a view whenever the observable object changes.

developer.apple.com

 

https://developer.apple.com/documentation/combine/published

 

Published | Apple Developer Documentation

A type that publishes a property marked with an attribute.

developer.apple.com

 

https://www.kodeco.com/books/swiftui-cookbook/v1.0/chapters/2-understanding-observableobject-observedobject

 

SwiftUI Cookbook, Chapter 2: Understanding ObservableObject & ObservedObject

Learn how to use the ObservableObject and ObservedObject property wrappers in SwiftUI for shared state management across multiple views.

www.kodeco.com

 

์ €์ž‘์žํ‘œ์‹œ (์ƒˆ์ฐฝ์—ด๋ฆผ)

'๐ŸŽ Dev > SwiftUI' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[SwiftUI] LifeCycle  (1) 2024.10.14
[SwiftUI] Navigation 1  (0) 2024.09.24
[SwiftUI] scrollTargetLayout๊ณผ ScrollTargetBehavior  (0) 2024.08.16
[SwiftUI] Property Wrapper ์ด์ •๋ฆฌ  (0) 2024.07.26
[SwiftUI] Frame  (0) 2024.07.22
'๐ŸŽ Dev/SwiftUI' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • [SwiftUI] LifeCycle
  • [SwiftUI] Navigation 1
  • [SwiftUI] scrollTargetLayout๊ณผ ScrollTargetBehavior
  • [SwiftUI] Property Wrapper ์ด์ •๋ฆฌ
Callie_
Callie_
  • Callie_
    CalliOS
    Callie_
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
    • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ
      • ๐ŸŽ APPLE
      • ๐ŸŽ Dev
        • Swift
        • UIKit
        • SwiftUI
        • Issue
        • ๊ตฌํ˜„
      • ๐ŸŽ Design
        • HIG
      • โš™๏ธ CS
      • ๐Ÿ’ก ์•Œ๊ณ ๋ฆฌ์ฆ˜
        • ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค
        • ๋ฐฑ์ค€
      • ๐ŸŸ๏ธ ์ง๊ด€๋กœ๊ทธ (์ถœ์‹œ์•ฑ)
        • ์—…๋ฐ์ดํŠธ
      • ๐ŸŒฑ SeSAC iOS 3๊ธฐ
  • ๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

    • ํ™ˆ
    • ํƒœ๊ทธ
  • ๋งํฌ

  • ๊ณต์ง€์‚ฌํ•ญ

  • ์ธ๊ธฐ ๊ธ€

  • ํƒœ๊ทธ

    IBAction
    .fullScreen
    ios
    Swift
    ์ƒ๋ช…์ฃผ๊ธฐ
    apply
    diffable
    DiffableDataSource
    layer.shadow
    ํ™”๋ฉด์ „ํ™˜
    TapGestureRecognizer
    SwiftUI
    TableViewCell
    modalPresentStyle
    Snapshot
    CustomView
    cornerradius
    clipsToBound
    Entry Point
    IBOutlet
    assets
    .OverFullScreen
    DidEndOnExit
    stroyboard
    Enum
    Infoํƒญ
    ๋„คํŠธ์›Œํฌํ†ต์‹ 
    CocoaTouchFramework
    addTarget
    SeSAC
  • ์ตœ๊ทผ ๋Œ“๊ธ€

  • ์ตœ๊ทผ ๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.0
Callie_
[SwiftUI] ObservableObject, ObservedObject, Published
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”