Skip to content

Latest commit

Β 

History

History
134 lines (94 loc) Β· 4 KB

Chapter10_Debugging.md

File metadata and controls

134 lines (94 loc) Β· 4 KB

Chapter 10: Debugging

πŸ»β€β„οΈ Printing events

print(_:to:) operator

  • publisher λ₯Ό 톡해 처리 되고 μžˆλŠ”μ§€ ν™•μ‹€ν•˜μ§€ μ•Šμ„ λ•Œ κ°€μž₯ λ¨Όμ € μ‚¬μš©
  • μ–΄λ–€ 일이 μΌμ–΄λ‚˜κ³  μžˆλŠ”μ§€μ— λŒ€ν•œ λ§Žμ€ 정보λ₯Ό 좜λ ₯ν•œλŠ” passthrough publisher
let subscription = (1...3).publisher 
	.print("publisher")
	.sink { _ in }

publisher: receive subscription: (1...3)
publisher: request unlimited
publisher: receive value: (1)
publisher: receive value: (2)
publisher: receive value: (3)
publisher: receive finished
  • Subscription 을 전달 λ°›μ•˜μ„ λ•Œ 좜λ ₯ν•˜κ³  upstream publisher 에 λŒ€ν•œ μ„€λͺ…을 보여쀀닀.
  • Subscriber의 μš”κ΅¬ μš”μ²­μ„ 좜λ ₯ν•΄μ„œ λͺ‡κ°œμ˜ μ•„μ΄ν…œμ΄ μš”μ²­ λ˜μ—ˆλŠ”μ§€ 보여쀀닀.
  • Upstream publisher κ°€ emit ν•œ λͺ¨λ“  값을 좜λ ₯ν•œλ‹€
  • λ§ˆμ§€λ§‰μœΌλ‘œ, completion 이벀트λ₯Ό 좜λ ₯ν•œλ‹€

μΆ”κ°€μ μœΌλ‘œ TextOutputSream 객체λ₯Ό κ°–λŠ” νŒŒλΌλ―Έν„°κ°€ μžˆλ‹€.

  • 직접 string 을 logger 에 좜λ ₯ ν•˜κ²Œ ν•  수 μžˆλ‹€.
  • ν˜„μž¬ λ‚ μ§œλ‚˜ μ‹œκ°„ 같은 정보λ₯Ό λ‘œκ·Έμ— μΆ”κ°€ ν•  수 μžˆλ‹€.
class TimeLogger: TextOutputSream {
	private var previous = Date()
	private let formatter = NSNumberFormatter()

	init() {
		formatter.maximumFractionDigits = 5
		formatter.minimumFractionDigits = 5

	func write(_ string: String) {
		let trimmed = string.trimmingCharacters(in: .whitespacesAndNewlines)
		guard !trimmed.isEmpty else { return }
		let now = Date()
		print("+\(formatter.string(for: now.timeIntervalSince(previous))!)s: \(string)")
		previous = now
	}
}

let subscription = (1...3).publisher
  .print("publisher", to: TimeLogger())
  .sink { _ in }

+0.00111s: publisher: receive subscription: (1...3)
+0.03485s: publisher: request unlimited
+0.00035s: publisher: receive value: (1)
+0.00025s: publisher: receive value: (2)
+0.00027s: publisher: receive value: (3)
+0.00024s: publisher: receive finished

πŸ»β€β„οΈ Acting on events - performing side effects

The

handleEvents(receiveSubscription:receiveOutput:receiveCompletion:receiveCancel:r eceiveRequest:)

publisher 의 생λͺ… μ£ΌκΈ° λ‚΄μ—μ„œ 이벀트λ₯Ό intercept ν•˜κ³  각각의 단계에 μ•‘μ…˜μ„ μ·¨ν•  수 μžˆλ‹€.

let request = URLSession.shared
	.dataTaskPublisher(for: URL(string: "https://www.raywenderlich.com/")!)

let subscription = requset
	.handleEvents(receiveSubscription: { _ in
	  print("Network request will start")
	}, receiveOutput: { _ in
	  print("Network request data received")
	}, receiveCancel: {
	  print("Network request cancelled")
	})
	.sink(receiveCompletion: { completion in
		print("Sink received completion: \(completion)")
	}) { data, _ in
		print("Sink received data: \(data)")
	}

Network request will start
Network request cancelled
Sink received data: 153253 bytes
Sink received completion: finished

πŸ»β€β„οΈ Using the debugger as a last resort

breakpointOnError()

  • Upstream publisher μ—μ„œ μ—λŸ¬λ₯Ό emit ν–ˆμ„λ•Œ, Xcode λŠ” 디버거에 break ν•˜κ³  μŠ€νƒμ„ λ³Ό 수 μžˆλ„λ‘ ν•΄μ£Όκ³  μ–΄λ””μ„œ μ™œ μ—λŸ¬κ°€ λ‚˜μ˜¨κ±΄μ§€ 찾게 ν•΄μ€€λ‹€.

breakpoint(receiveSubscription:receiveOutput:receiveCompletion:)

  • λ‹€μ–‘ν•œ μ΄λ²€νŠΈμ— intercept ν•˜κ³  μΌ€μ΄μŠ€ λ§ˆλ‹€ 디버거λ₯Ό λ©ˆμΆ”κ³  싢은지 κ²°μ •ν•œλ‹€.
.breakpoint(receiveOutput: { value in
	return value > 10 && value < 15
}

쑰건적으둜 ꡬ독과 completion time 을 break ν•  수 μžˆμ§€λ§Œ, handleEvents operator 같은 μ·¨μ†ŒλŠ” intercept ν•  수 μ—†λ‹€.

Note : Playground μ—μ„œλŠ” breakpoint publisher κ°€ λ™μž‘ν•˜μ§€ μ•ŠλŠ”λ‹€. 싀행이 interrupt λ˜μ—ˆλ‹€λŠ” μ—λŸ¬λŠ” λ³Ό 수 μžˆμ§€λ§Œ, 디버거에 듀어가진 μ•ŠλŠ”λ‹€.


πŸ”‘ Key points

  • print operator 둜 publisher 의 생λͺ…μ£ΌκΈ°λ₯Ό 좔적 ν•  수 μžˆλ‹€.
  • TextOutputStream 을 μƒμ„±ν•΄μ„œ κ²°κ³Ό string 을 μ»€μŠ€ν…€ ν•  수 μžˆλ‹€.
  • handleEvents operator λŠ” 생λͺ…μ£ΌκΈ° 이벀트λ₯Ό intercept ν•˜κ³  μ•‘μ…˜μ„ μˆ˜ν–‰ν•œλ‹€.
  • breakpointOnError 와 breakpoint operator λŠ” νŠΉμ • 이벀트λ₯Ό break ν•œλ‹€.