Combine을 이용해서 디버깅하는 방법으로는 다음과 같다.
func bindMainViewModel() {
mainViewModel.cameraUpdate
.receive(on: DispatchQueue.main)
.print("cameraUpdate")
.sink(receiveValue: { [weak self] cameraUpdate in
...
}).store(in: &cancellables)
cameraUpdate: receive subscription: (ReceiveOn) // 구독함
cameraUpdate: request unlimited // publisher가 생성하는 값들을 제한없이 요청
cameraUpdate: receive value: (nil) // 초기값
cameraUpdate: receive value: (Optional(<NMFParamUpdate: 0x280faf020>)) // 값 업데이트됨
final class TimeIntervalLogger: TextOutputStream {
private let formatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.maximumFractionDigits = 5
formatter.minimumFractionDigits = 5
return formatter
}()
private var previous = Date()
func write(_ string: String) {
guard !string.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else { return }
let now = Date()
guard let timeInterval = formatter.string(for: now.timeIntervalSince(previous)) else { return }
previous = now
print("\(timeInterval)s \(string)")
}
}
func bindMainViewModel() {
mainViewModel.cameraUpdate
.print("cameraUpdate", to: TimeIntervalLogger())
.sink(receiveValue: { [weak self] cameraUpdate in
...
}).store(in: &cancellables)
0.00036s cameraUpdate: receive subscription: (ReceiveOn)
0.00009s cameraUpdate: request unlimited
0.17119s cameraUpdate: receive value: (nil)
func bindMainViewModel() {
mainViewModel.cameraUpdate
.print("cameraUpdate", to: TimeIntervalLogger())
.handleEvents(receiveSubscription: { _ in print("구독 받음") },
receiveOutput: { _ in print("구독 결과") },
receiveCompletion: { _ in print("구독되거나 오류로 종료됨") },
receiveCancel: { print("구독 취소") },
receiveRequest: { _ in print("구독 추가 요청") })
구독 받음
구독 요청
cameraUpdate: request unlimited
cameraUpdate: receive value: (nil)
구독 결과
cameraUpdate: receive value: (Optional(<NMFParamUpdate: 0x280eba580>))
구독 결과
0.00039s cameraUpdate: receive subscription: (ReceiveOn)
구독 받음
구독 추가 요청
0.00010s cameraUpdate: request unlimited
구독 취소
0.00007s cameraUpdate: receive cancel
func bindMainViewModel() {
mainViewModel.cameraUpdate
.breakpointOnError()
.breakpoint( receiveOutput: { value in
return value == nil
})