클래스 간 데이터를 교환하기 위해서는 의존성 주입을 사용하여 해결할 수 있습니다

 

코드를 짜다 보면 ObservableObject 클래스 간의 데이터를 주고받아야 하는 경우가 있습니다.

이때 이런 ObservableObject 클래스를 동시에 뷰와 같이 사용해야 할 때 막히는 경우가 있습니다.

 

다음은 2개의 ObservableObject 클래스입니다.

class MusicPlayer: ObservableObject
class iOSToWatch: NSObject, ObservableObject

 

기능을 간단하게 설명하자면 MusicPlayer에서 iOSToWatch 클래스로부터 심박수를 받아 데이터를 서버에 전송하여 노래를 받아오는 기능입니다. 이때 두 클래스 간 데이터를 교환해야 하는데 그러기 위해서는 다음과 같은 절차를 밟습니다.

 

아래처럼 MusicPlayer에 iosToWatch 클래스를 넣으면 클래스로부터 받은 심박수 또는 다른 데이터들을 데이터를 공유하면서 사용할 수 있게 되며 이것을 의존성 주입이라고 합니다.

 

추가로 의존성 주입을 적용하여 싱글톤을 사용하지 않아도 된다는 점도 숙지하면 좋습니다.

@main
struct team_projectApp: App {
    @StateObject var musicPlayer = MusicPlayer(iosToWatch: iOSToWatch())
@MainActor
class MusicPlayer: ObservableObject {
    @State var iosToWatch: iOSToWatch
    init(iosToWatch: iOSToWatch) {
        self.iosToWatch = iosToWatch
        setupRemoteCommands()
    }

 

다른 예시 코드로 마무리 하겠습니다.

@main
struct ICPProjectApp: App {
    @StateObject private var mapViewModel: MapViewModel

    init() {
        // MapViewModel 생성 시 RouteViewModel을 주입 // 이것을 의존성 주입이라고 함
        let routeVM = RouteViewModel()
        _mapViewModel = StateObject(wrappedValue: MapViewModel(routeVM: routeVM))
    }

 

@MainActor
class DependencyInjectionViewModel: NSObject, ObservableObject {
    var DependencyInjectionVM: DependencyInjectionViewModel
    
    init(routeVM: DependencyInjectionViewModel) {
        self.DependencyInjectionVM = routeVM

 

이렇게 하면 MapViewModel 에서 업데이트하는 RouteViewModel 의 값을 추적 밑 뷰를 다시 랜더링하는데 사용할 수 있습니다.

struct SelectedDetailView: View {
    @EnvironmentObject var mapState: MapViewModel

 

위처럼 MapViewModel 을 만들었다면 아래처럼 의존성 주입을 활용하여 MapViewModel 의 routeVM 을 통해 해당 값을 사용할 수 있게 됩니다.

.onChange(of: mapState.routeVM.walkRoute?.route) { _, newValue in
    print("Walking route expected time: \(newValue?.expectedTravelTime ?? 0)")
}

 

ytw_developer