Futures is a cross-platform framework for simplifying asynchronous programming, written in Swift.

Overview

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

  • Ubuntu 14.04
  • macOS 10.9
  • tvOS 9.0
  • iOS 8.0
  • watchOS 2.0

Architecture

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

  • Promise, a single assignment container producing a Future
  • Future, a read-only container resolving into either a value, or an error

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:

  • resolved, if its value is set
  • fulfilled, if the value is set, and successful
  • rejected, if the value is set, and a failure (error)

Usage

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

  • whenResolved, if you're interested in both a value and a rejection error
  • whenFulfilled, if you only care about the values
  • whenRejected, if you only care about the error

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

  • flatMap(), to execute another future based on the result of the current one
  • flatMapIfRejected(), to recover from a potential error resulting from the current future
  • flatMapThrowing(), to transform the fulfilled value of the current future or return a rejected future
  • map(), to transform the fulfilled value of the current future
  • recover(),to transform a rejected future into a fulfilled future
  • always(), to execute a Void returning closure regardless of whether the current future is rejected or resolved
  • and(), to combine the result of two futures into a single tuple
  • Future.reduce(), to combine the result of multiple futures into a single future

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, 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

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

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

You might also like...
⚡️ Fast async task based Swift framework with focus on type safety, concurrency and multi threading
⚡️ Fast async task based Swift framework with focus on type safety, concurrency and multi threading

Our apps constantly do work. The faster you react to user input and produce an output, the more likely is that the user will continue to use your appl

Pomodoro is a macOS status bar application written in SwiftUI, which allows you to control your work and break time, exploiting the pomodoro-technique.
Pomodoro is a macOS status bar application written in SwiftUI, which allows you to control your work and break time, exploiting the pomodoro-technique.

Pomodoro Pomodoro is a macOS status bar application which allows you to control your work and break time. Through this application you will be able to

Hydra ⚡️ Lightweight full-featured Promises, Async & Await Library in Swift
Hydra ⚡️ Lightweight full-featured Promises, Async & Await Library in Swift

Lightweight full-featured Promises, Async & Await Library in Swift What's this? Hydra is full-featured lightweight library which allows you to write b

Kommander is a Swift library to manage the task execution in different threads.
Kommander is a Swift library to manage the task execution in different threads.

A lightweight, pure-Swift library for manage the task execution in different threads. Through the definition a simple but powerful concept, Kommand.

SwiftCoroutine - Swift coroutines for iOS, macOS and Linux.
SwiftCoroutine - Swift coroutines for iOS, macOS and Linux.

Many languages, such as Kotlin, Go, JavaScript, Python, Rust, C#, C++ and others, already have coroutines support that makes the async/await pattern i

Venice - Coroutines, structured concurrency and CSP for Swift on macOS and Linux.
Venice - Coroutines, structured concurrency and CSP for Swift on macOS and Linux.

Venice provides structured concurrency and CSP for Swift. Features Coroutines Coroutine cancelation Coroutine groups Channels Receive-only chan

Elegant ⏱ interface for Swift apps

Each Elegant ⏱ interface for Swift apps Each is a NSTimer bridge library written in Swift. Features Requirements Installation Usage Leaks License Feat

 GCDTimer - Well tested Grand Central Dispatch (GCD) Timer in Swift
GCDTimer - Well tested Grand Central Dispatch (GCD) Timer in Swift

GCDTimer Well tested Grand Central Dispatch (GCD) Timer in Swift. Checkout the test file. Usage Long running timer import GCDTimer

Schedule timing task in Swift using a fluent API. (A friendly alternative to Timer)
Schedule timing task in Swift using a fluent API. (A friendly alternative to Timer)

Schedule(简体中文) Schedule is a timing tasks scheduler written in Swift. It allows you run timing tasks with elegant and intuitive syntax. Features Elega

Releases(1.6.1)
Owner
David Ask
iOS developer at heart, former art director. Available for hire.
David Ask
Syntactic sugar in Swift for asynchronous dispatches in Grand Central Dispatch

Async Now more than syntactic sugar for asynchronous dispatches in Grand Central Dispatch (GCD) in Swift Async sugar looks like this: Async.userInitia

Tobias Due Munk 4.6k Dec 27, 2022
AwaitKit is a powerful Swift library which provides a powerful way to write asynchronous code in a sequential manner.

AwaitKit is a powerful Swift library inspired by the Async/Await specification in ES8 (ECMAScript 2017) which provides a powerful way to write asynchronous code in a sequential manner.

Yannick Loriot 752 Dec 5, 2022
Syntactic sugar in Swift for asynchronous dispatches in Grand Central Dispatch (iOS7+ and OS X 10.9+ compatible)

Async.legacy Syntactic sugar in Swift for asynchronous dispatches in Grand Central Dispatch (GCD) Async rewritten for iOS7 and OS X 10.9 Compatibility

Joseph Lord 31 Jul 1, 2019
AsyncTimer is a precision asynchronous timer. You can also use it as a countdown timer

AsyncTimer ?? Features Can work as a countdown timer Can work as a periodic Timer Can work as a scheduled timer Working with user events (like: scroll

Adrian Bobrowski 26 Jan 1, 2023
A complete set of primitives for concurrency and reactive programming on Swift

A complete set of primitives for concurrency and reactive programming on Swift 1.4.0 is the latest and greatest, but only for Swift 4.2 and 5.0 use 1.

AsyncNinja 156 Aug 31, 2022
Operation Oriented Programming in Swift

Flow Flow is a lightweight Swift library for doing operation oriented programming. It enables you to easily define your own, atomic operations, and al

John Sundell 218 Feb 6, 2022
Egg-Timer - Intermediate Swift Programming - Control Flow and Optionals

Egg-Timer Intermediate Swift Programming - Control Flow and Optionals What I lea

null 0 Jan 10, 2022
A wrapper of Grand Central Dispatch written in Swift

GCD A wrapper of Grand Central Dispatch written in Swift. Examples gcd // submit your code for asynchronous execution on a global queue with high prio

Le Van Nghia 75 May 19, 2022
Slack message generator and API client, written in Swift with Result Builders and Concurrency

Slack Message Client This package provides a Swift object model for a Slack Block Kit message, as well as a Result Builder convenience interface for e

Mike Lewis 2 Jul 30, 2022
🎭 Swift async/await & Actor-powered effectful state-management framework.

?? Actomaton ??‍?? Actor + ?? Automaton = ?? Actomaton Actomaton is Swift async/await & Actor-powered effectful state-management framework inspired by

Yasuhiro Inami 199 Dec 20, 2022