Instruction

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

AsyncStream

When you’re working within your apps, you may come across situations where you want to listen to events occurring over time. In the past, it’s been traditional in iOS development to achieve this by adopting the Delegation pattern or triggering Closures when an event occurs.

class TripMonitor {
  var newTripHandler: ((Trip) -> Void)?

  func startMonitoringForTrips() {
    // some code to begin monitoring for new trips.
    let newTrip = Trip()
    
    newTripHandler?(newTrip)
  }

  func stopMonitoringForTrips() {
    // Stop monitoring for new trips.
  }
}

class TripStore {
  var tripMonitor: TripMonitor
  
  init(tripMonitor: TripMonitor) {
    self.tripMonitor = tripMonitor
    
    self.tripMonitor.newTripHandler = { [weak self] trip in
      self?.handleTrip(trip: trip)
    }
    
    self.tripMonitor.startMonitoringForTrips()
  }
  
  func handleTrip(trip: Trip) {
    // Handle trip
  }
}
class TripMonitor {
  var newTripHandler: ((Trip) -> Void)?

  func startMonitoringForTrips() {

    // some code to begin monitoring for new trips.
    // ...

    let newTrip = Trip()
    newTripHandler?(newTrip)
  }

  func stopMonitoringForTrips() {
    // Stop monitoring for new trips.
  }
}

// 1
extension TripMonitor {

  var trips: AsyncStream<Trip> {
    // 2
    AsyncStream { continuation in
      newTripHandler = { trip in
        // 3
        print("Yielding New Trip: \(trip)")
        continuation.yield(trip)
      }
      // 4
      continuation.onTermination = { @Sendable _ in
        self.stopMonitoringForTrips()
      }

      self.startMonitoringForTrips()
    }
  }
}


class TripStore {
  
  // 5
  let tripMonitor = TripMonitor()

  // 6
  func listenForTrips() async {
    // 7
    for await trip in tripMonitor.trips {
      print("New Trip: \(trip)")
      handleTrip(trip: trip)
    }
    
    print("Stream finished.")
  }

  func handleTrip(trip: Trip) {
    // Handle trip
  }
}
See forum comments
Download course materials from Github
Previous: Introduction Next: Demo