Latest 0.3.0
Homepage https://github.com/shopgun/swift-future
License MIT
Platforms ios 8.0, osx 10.10, tvos 9.0, watchos 2.0
Authors

🕰 Future

Swift 5
Build Status
Cocoapods
License

A Future just represents some ‘work’, that may take some time (or not).

The power of Futures is that they can be chained togther, producing a single Future object that contains all the work of all the component Futures.

Furthermore, the work of this Future isnt done until you actually run the future.

Here is an example of the kinds of complex logic possible with Futures:

struct User: Codable {
    var id: String
    var name: String
}

struct Food: Codable {
    var type: String
    var tastiness: Int
}

// Make a future that loads a user value from the file "User.json"
let loadFileUser: FutureResult<User> = Bundle.main
    .loadData(forResource: "User.json")
    .flatMapResult(User.decodeJSON(from:))

// Make a future that loads food value from the json string
let loadStringFood: FutureResult<Food> = Future<String>
    .init(value: #"{ "type": "curry", "tastiness": 1000 }"#)
    .map({ $0.data(using: .utf8)! })
    .flatMap(Food.decodeFutureJSON(from:))

// Make a future that loads another user value from a network request
let loadNetworkUser: FutureResult<User> = URLSession.shared
    .dataTaskFutureResult(with: URLRequest(url: URL(string: "https://foo.bar")!))
    .mapResult({ $0.data })
    .flatMapResult(User.decodeFutureJSON(from:))

// zip the 3 futures together and, if all successful, convert the response into a string.
let combinedFuture = zipResult3With(
    loadStringFood,
    loadFileUser,
    loadNetworkUser
) { (food: $0, user: $1, networkUser: $2) }
    .mapResult({
        "($0.user.name) likes ($0.food.type) x($0.food.tastiness)... networkUser: '($0.networkUser.name)'"
    })

// once it is finally run, print the result
combinedFuture.run { result in
    print(result)
} 

Future areas to improve:

  • FutureOptional – add tests and functionality similar to Future<Result<_,_>>
  • Cancellable – Somehow allow Futures to provide cancellable tokens.
  • More utility extensions
    • UIImageView().setImage(Future<UIImage?>)
    • CLGeocoder().geocode(...) -> FutureResult<[CLPlacemark]>
    • Maybe CLLocationManager… how to handle delegates? Future’s arent the right thing for streams of events, I think. But sometimes we need 1-hit delegate calls.

Latest podspec

{
    "name": "ShopGun-Future",
    "module_name": "Future",
    "version": "0.3.0",
    "summary": "ud83dudd70 A simple Swift Future type",
    "description": "Future is a lightweight type that expresses the idea of 'work'. nnIt is easily chainable, allowing you to build up complex Futures from smaller units of work.nnNone of the work expressed in a Future is performed until the you explicitly run it.nnThis library includes a number of extra wrappers around common operations, allowing them to easily chained with other futures.",
    "homepage": "https://github.com/shopgun/swift-future",
    "license": "MIT",
    "authors": {
        "Laurie Hufford": "[email protected]"
    },
    "social_media_url": "https://twitter.com/shopgun",
    "source": {
        "git": "https://github.com/shopgun/swift-future.git",
        "tag": "0.3.0"
    },
    "swift_versions": "5.0",
    "platforms": {
        "ios": "8.0",
        "osx": "10.10",
        "tvos": "9.0",
        "watchos": "2.0"
    },
    "source_files": [
        "Sources",
        "Sources/**/*.swift"
    ]
}

Pin It on Pinterest

Share This