Home

Awesome

Futures

Tests

Futures is a cross-platform framework for simplifying asynchronous programming, written in Swift. It's lightweight, fast, and easy to understand.

Supported Platforms

Architecture

Fundamentally, Futures is a very simple framework, that consists of two types:

In many promise frameworks, a promise is undistinguished from a future. This introduces mutability of a promise that gets passed around. In Futures, a Future is the observable value while a Promise is the function that sets the value.

Futures are observed, by default, on a single concurrent dispatch queue. This queue can be modified by assigning a different queue to DispatchQueue.futures. You can also specify a queue of your choice to each callback added to a future .

A future is regarded as:

Usage

When a function returns a Future<Value>, you can either decide to observe it directly, or continue with more asynchronous tasks. For observing, you use:

If you have more asynchronous work to do based on the result of the first future, you can use

Note that you can specify an observation dispatch queue for all these functions. For instance, you can use flatMap(on: .main), or .map(on: .global()). By default, the queue is DispatchQueue.futures.

As a simple example, this is how some code may look:

let future = loadNetworkResource(
    from: URL("http://someHost/resource")!
).flatMapThrowing { data in
    try jsonDecoder.decode(SomeType.self, from: data)
}.always {
    someFunctionToExecuteRegardless()
}

future.whenFulfilled(on: .main) { someType in
    // Success
}

future.whenRejected(on: .main) { error in
    // Error
}

To create your functions returning a Future<T>, you create a new pending promise, and resolve it when appropriate.

func performAsynchronousWork() -> Future<String> {
    let promise = Promise<String>()

    DispatchQueue.global().async {
        promise.fulfill(someString)

        // If error
        promise.reject(error)
    }

    return promise.future
}

You can also use shorthands.

promise {
     try jsonDecoder.decode(SomeType.self, from: data)
} // Future<SomeType>

Or shorthands which you can return from asynchronously.

promise(String.self) { completion in
    /// ... on success ...
    completion(.fulfill("Some string"))
    /// ... if error ...
    completion(.reject(anError))
} // Future<String>

Documentation

The complete documentation can be found here.

Getting started

Futures can be added to your project either using Carthage or Swift package manager.

If you want to depend on Futures in your project, it's as simple as adding a dependencies clause to your Package.swift:

dependencies: [
    .package(url: "https://github.com/davidask/Futures.git", from: "1.6.0")
]

Or, add a dependency in your Cartfile:

github "davidask/Futures"

More details on using Carthage can be found here.

Lastly, import the module in your Swift files

import Futures

Contribute

Please feel welcome contributing to Futures, check the LICENSE file for more info.

Credits

David Ask