2026-07-03 21:33:07 +02:00
|
|
|
import Foundation
|
|
|
|
|
|
|
|
|
|
/// A service that captures audio from a microphone for the Recording feature.
|
|
|
|
|
///
|
|
|
|
|
/// ``RecordingView`` attaches the service to its model at initialization, so the audio capture can be swapped without touching the feature's
|
|
|
|
|
/// state machine — for example, with a real microphone backend in the app, or with a mock in unit tests.
|
2026-07-04 13:41:56 +02:00
|
|
|
public protocol Capturing: Sendable {
|
2026-07-03 21:33:07 +02:00
|
|
|
|
2026-07-04 15:19:26 +02:00
|
|
|
// MARK: Properties
|
|
|
|
|
|
|
|
|
|
/// The stream of events the service emits outside its method calls.
|
|
|
|
|
///
|
|
|
|
|
/// Defaults to an empty stream that finishes immediately, for services that emit no events.
|
|
|
|
|
var events: AsyncStream<CapturingEvent> { get }
|
|
|
|
|
|
2026-07-04 12:03:19 +02:00
|
|
|
// MARK: Methods
|
|
|
|
|
|
2026-07-03 21:33:07 +02:00
|
|
|
/// Starts a new audio recording from the microphone.
|
|
|
|
|
func start() async throws
|
|
|
|
|
|
|
|
|
|
/// Pauses the ongoing recording.
|
|
|
|
|
func pause() async throws
|
|
|
|
|
|
|
|
|
|
/// Resumes a paused recording.
|
|
|
|
|
func resume() async throws
|
|
|
|
|
|
|
|
|
|
/// Stops the recording.
|
|
|
|
|
///
|
2026-07-04 15:06:55 +02:00
|
|
|
/// - Returns: The location of the audio file captured since the recording started.
|
|
|
|
|
func stop() async throws -> URL
|
2026-07-03 21:33:07 +02:00
|
|
|
|
|
|
|
|
}
|
2026-07-04 15:19:26 +02:00
|
|
|
|
|
|
|
|
// MARK: - Implementations
|
|
|
|
|
|
|
|
|
|
public extension Capturing {
|
|
|
|
|
|
|
|
|
|
/// The empty stream of events, which finishes immediately, for services that emit no events.
|
|
|
|
|
var events: AsyncStream<CapturingEvent> {
|
|
|
|
|
AsyncStream { continuation in
|
|
|
|
|
continuation.finish()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MARK: - Events
|
|
|
|
|
|
|
|
|
|
/// An event emitted by a ``Capturing`` service outside its method calls.
|
2026-07-05 16:16:53 +02:00
|
|
|
public enum CapturingEvent: Equatable, Sendable {
|
2026-07-04 15:19:26 +02:00
|
|
|
/// The system interrupted the ongoing capture, pausing it.
|
|
|
|
|
case interrupted
|
2026-07-05 16:16:53 +02:00
|
|
|
/// The system ended the interruption of the capture, hinting whether the capture may resume right away.
|
|
|
|
|
case interruptionEnded(shouldResume: Bool)
|
2026-07-04 15:19:26 +02:00
|
|
|
}
|