Reactive Programming in iOS with Combine

Feb 4 2021 Swift 5.3, macOS 11.0, Xcode 12.2

Part 4: Timing, Scheduling and Sequencing Operators

23. Delay and Collect

Lesson Complete

Play Next Lesson
Next
Save for later
About this episode

See course reviews

See forum comments
Cinema mode Mark as Complete Download course materials
Previous episode: 22. Introduction Next episode: 24. Debounce and Throttle

This video was last updated on Feb 4 2021

Heads up... You've reached locked video content where the transcript will be shown as obfuscated text.

You can unlock the rest of this video course, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.

Have you ever heard the saying “Timing is everything”? That is especially true in Combine, which models asynchronous event flows over time. It’s no surprise then that Combine has a set of operators that deal with time, in particular how sequences react to and transform values over time. In this episode you’ll learn about two timing operators: delay and collect.

let valuesPerSecond = 1.0
let delayInSeconds = 1.5
// 1
let sourcePublisher = PassthroughSubject<Date, Never>()
// 2
let delayedPublisher = sourcePublisher.delay(for: .seconds(delayInSeconds), scheduler: DispatchQueue.main)
// 3
let subscription = Timer
  .publish(every: 1.0 / elementsPerSecond, on: .main, in: .common)
  .autoconnect()
  .subscribe(sourcePublisher)
// 4
let sourceTimeline = TimelineView(title: "Emitted values (\(elementsPerSecond) per sec.):")

// 5
let delayedTimeline = TimelineView(title: "Delayed values (with a \(delayInSeconds)s delay):")
// 6
let view = VStack(spacing: 50) {
  sourceTimeline
  delayedTimeline
}

// 7
PlaygroundPage.current.liveView = UIHostingController(rootView: view)
sourcePublisher.displayEvents(in: sourceTimeline)
delayedPublisher.displayEvents(in: delayedTimeline)

let valuesPerSecond = 1.0
let collectTimeStride = 4
// 1
let sourcePublisher = PassthroughSubject<Date, Never>()

// 2
let collectedPublisher = sourcePublisher
  .collect(.byTime(DispatchQueue.main, .seconds(collectTimeStride)))

let subscription = Timer
  .publish(every: 1.0 / valuesPerSecond, on: .main, in: .common)
  .autoconnect()
  .subscribe(sourcePublisher)
let sourceTimeline = TimelineView(title: "Emitted values:")
let collectedTimeline = TimelineView(title: "Collected values (every \(collectTimeStride)s):")

let view = VStack(spacing: 40) {
  sourceTimeline
  collectedTimeline
}

PlaygroundPage.current.liveView = UIHostingController(rootView: view)
sourcePublisher.displayEvents(in: sourceTimeline)
collectedPublisher.displayEvents(in: collectedTimeline)
let collectedPublisher = sourcePublisher
  .collect(.byTime(DispatchQueue.main, .seconds(collectTimeStride)))
  .flatMap { dates in dates.publisher }