CoroutineScheduler

public protocol CoroutineScheduler

A protocol that defines how to execute a task.

This protocol has extension methods that allow to launch coroutines on a current scheduler. Inside the coroutine you can use such methods as Coroutine.await(_:), CoFuture.await(), and CoroutineScheduler.await(_:) to suspend the coroutine without blocking a thread and resume it when the result is ready.

To launch a coroutine, use CoroutineScheduler.startCoroutine(_:).

//execute coroutine on the main thread
DispatchQueue.main.startCoroutine {

    //extension that returns CoFuture<(data: Data, response: URLResponse)>
    let dataFuture = URLSession.shared.dataTaskFuture(for: url)

    //await result that suspends coroutine and doesn't block the thread
    let data = try dataFuture.await().data

}

The framework includes the implementation of this protocol for DispatchQueue and you can easily make the same for other schedulers as well.

extension OperationQueue: CoroutineScheduler {

    public func scheduleTask(_ task: @escaping () -> Void) {
        addOperation(task)
    }

}
  • Performs the task at the next possible opportunity.

    Declaration

    Swift

    func scheduleTask(_ task: @escaping () -> Void)
  • startCoroutine(_:) Extension method

    Start a new coroutine on the current scheduler.

    As an example, with Coroutine.await(_:) you can wrap asynchronous functions with callbacks to synchronously receive its result without blocking the thread.

    //start new coroutine on the main thread
    DispatchQueue.main.startCoroutine {
        //execute someAsyncFunc() and await result from its callback
        let result = Coroutine.await { someAsyncFunc(callback: $0) }
    }
    

    Declaration

    Swift

    @inlinable
    public func startCoroutine(_ task: @escaping () throws -> Void)

    Parameters

    task

    The closure that will be executed inside coroutine. If the task throws an error, then the coroutine will be terminated.

  • await(_:) Extension method

    Start a coroutine and await its result. Must be called inside other coroutine.

    This method allows to execute given task on other scheduler and await its result without blocking the thread.

    //start coroutine on the main thread
    DispatchQueue.main.startCoroutine {
        //execute someSyncFunc() on global queue and await its result
        let result = DispatchQueue.global().await { someSyncFunc() }
    }
    

    Throws

    Rethrows an error from the task.

    Declaration

    Swift

    @inlinable
    public func await<T>(_ task: () throws -> T) rethrows -> T

    Parameters

    task

    The closure that will be executed inside coroutine.

    Return Value

    Returns the result of the task.

  • coroutineFuture(_:) Extension method

    Starts a new coroutine and returns its future result.

    This method allows to execute a given task asynchronously and return CoFuture with its future result immediately.

    //execute someSyncFunc() on global queue and return its future result
    let future = DispatchQueue.global().coroutineFuture { someSyncFunc() }
    //start coroutine on main thread
    DispatchQueue.main.startCoroutine {
        //await result of future
        let result = try future.await()
    }
    

    Declaration

    Swift

    @inlinable
    public func coroutineFuture<T>(_ task: @escaping () throws -> T) -> CoFuture<T>

    Parameters

    task

    The closure that will be executed inside the coroutine.

    Return Value

    Returns CoFuture with the future result of the task.