본문 바로가기

iOS/SwiftUI

SwiftUI) MVVM과 Combine

학습 정리

Combine

What is Combine?

비동기적(Asynchronous) 이벤트를 처리하기 위한 애플의 프레임워크
iOS 개발을 위한 코드는 Asynchronous event를 처리할 일이 많다. 이 떼 Combine을 사용하면 코드를 단순화 해준다.

Advantages of Combine

No More Callback Hells!

dirtyCode

위 코드는 어떤 동작을 하고 있는지 이해하기 어렵다. 이런식으로 코드가 지저분해지는 것을 막을 수 있다.

Key Concepts of Combine

protocol Publisher {
    associatedtype Output
    associatedtype Failure: Error

    func subscribe<S: Subscriber>(_ subscriber: S)
        where S.Input == Output, S.Failure == Failure
}
protocol Subscriber {
    associatedtype Input
    associatedtype Failure: Error

    func receive(subscription: Subscription)
    func receive(_ value: Subscribers.Demand)
    func receive(completion: Subscribers.Completion<Failure>)
}

이름에서 볼 수 있듯이 Publisher는 values를 publish 하고 Subscriber는 subscribe or listen한다.

ViewModel 적용

class CourseViewModel: ObservableObject {
    @Published var messages = "Messages inside observable object"
}

struct ContentView: View {
    var coursesVM = CousesViewModel()

    var body: some View {
        NavigationView {
            ScrollView {
                Text(coursesVM.messages)
            }.navigationBarTitle("Courses")
            .navigationBarItems(trailing: Button(action: {
                print("Fetching json data")

                self.coursesVM.messages = "SOMETHING ELSE"
            }, label: {
                text("Fetch Courses")
            }))
        }
    }
}

처음 의도했던 방식은 Fetch Courses 버튼을 눌렀을 때 화면에 보여지는 메세지 즉, coursesVM.messages"SOMETHING ELSE"로 변경되는 것이다. 기대와 달리 이 코드를 실행시키면 아무것도 변하지 않는다. 그 이유는 coursesVMdynamic view property가 아니기 때문이다. 다음과 같이 coursesVM 앞에 @ObservedObject를 추가해주면 된다.

@ObservedObject var coursesVM = CousesViewModel()

ObservedObject

A dynamic viewproperty that subscribes to a ObservableObject automatically invalidating the view when it changes
ObservedObject-developer.apple

이런 방식으로 ViewModelView 내부에서 이용되고 변화될 Properties를 가진다.