{"id":20713142,"url":"https://github.com/aladinway/promisedfuture","last_synced_at":"2025-04-23T07:55:52.624Z","repository":{"id":48639561,"uuid":"99351220","full_name":"AladinWay/PromisedFuture","owner":"AladinWay","description":"A Swift based Future/Promises framework to help writing asynchronous code in an elegant way","archived":false,"fork":false,"pushed_at":"2021-07-16T11:36:11.000Z","size":66,"stargazers_count":73,"open_issues_count":2,"forks_count":13,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-23T07:55:45.533Z","etag":null,"topics":["asynchronous","deffered","futures","ios","promise","swift"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AladinWay.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-08-04T14:32:42.000Z","updated_at":"2024-05-27T16:56:03.000Z","dependencies_parsed_at":"2022-09-05T15:41:37.004Z","dependency_job_id":null,"html_url":"https://github.com/AladinWay/PromisedFuture","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AladinWay%2FPromisedFuture","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AladinWay%2FPromisedFuture/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AladinWay%2FPromisedFuture/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AladinWay%2FPromisedFuture/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AladinWay","download_url":"https://codeload.github.com/AladinWay/PromisedFuture/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250395208,"owners_count":21423377,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asynchronous","deffered","futures","ios","promise","swift"],"created_at":"2024-11-17T02:23:42.070Z","updated_at":"2025-04-23T07:55:52.606Z","avatar_url":"https://github.com/AladinWay.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n \u003cp align=\"center\"\u003e\n\t\u003cimg src=\"http://itechnodev.com/img/logo.png\" align=\"center\" alt=\"logo\"\u003e\n\u003c/p\u003e\n\u003cbr \\\u003e\n\n\n[![CI Status](http://img.shields.io/travis/AladinWay/PromisedFuture.svg?style=flat)](https://travis-ci.org/AladinWay/PromisedFuture)\n[![Version](https://img.shields.io/cocoapods/v/PromisedFuture.svg?style=flat)](http://cocoapods.org/pods/PromisedFuture)\n[![License](https://img.shields.io/cocoapods/l/PromisedFuture.svg?style=flat)](http://cocoapods.org/pods/PromisedFuture)\n[![Platform](https://img.shields.io/cocoapods/p/PromisedFuture.svg?style=flat)](http://cocoapods.org/pods/PromisedFuture)\n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n\n   \n## PromisedFuture\n**PromisedFuture** is a lightweight implementation of Futures/Promises. \n`PromisedFuture` helps to write readable and comprehensible asynchronous code. \n\nUsually the callback mechanism is used when working with asynchronous tasks. It should get the job done for some use cases, but usually we need to perform more that one asynchronous operation, so we have to nest the second operation inside the completion block of the first one, but when we have nested callbacks it starts to get messy, the code is not friendly in term of maintainability, readability and control, and this leads to the Pyramid of doom, Callback hell and error handling issues.\n\n**PromisedFuture** is here to rescue, the code will go from this:\n\n```\nAPIClient.login(email: \"test@gmail.com\", password: \"myPassword\", completion: { result in\n    switch result {\n    case .success(let user):\n        APIClient.userArticles(userID: user.id, completion: { result in\n            switch result {\n            case .success(let articles):\n                APIClient.getArticle(id: articles.last!.id, completion: { result in\n                    switch result {\n                    case .success(let article):\n                        print(article)\n                    case .failure(let error):\n                        print(error)\n                    }\n                })\n            case .failure(let error):\n                print(error)\n            }\n        })\n    case .failure(let error):\n        print(error)\n    }\n})\n\n```\n\nto this: \n\n\n```\nAPIClient.login(email: \"test@gmail.com\", password: \"myPassword\")\n         .map({$0.id})\n         .andThen(APIClient.userArticles)\n         .map({$0.last!.id})\n         .andThen(APIClient.getArticle)\n         .execute(onSuccess: { article in\n            print(article)\n         }, onFailure: {error in\n            print(error)\n         })\n```\n\n## Features\n\n- [x] Chainable asynchronous operations.\n- [x] Lightweight and simple to use (just ≈ 40 lines of code).\n- [x] Fully unit tested.\n- [x] Fully Documented.\n\n\n## Requirements\n\n- iOS 10.0+ / macOS 10.12+ / tvOS 10.0+ / watchOS 3.0+\n- Xcode 9.0+\n- Swift 4.0+\n\n## Example\n\nTo run the example project, clone the repo, then open the workspace `PromisedFuture.xcworkspace` run using `iOS Example` scheme.\n\n## Installation\n\n### CocoaPods\n\n[CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. You can install it with the following command:\n\n```bash\n$ gem install cocoapods\n```\n\nTo integrate PromisedFuture into your Xcode project using CocoaPods, specify it in your `Podfile`:\n\n```ruby\nuse_frameworks!\n\npod 'PromisedFuture'\n```\n\nThen, run the following command:\n\n```bash\n$ pod install\n```\n\n\n### Carthage\n\n[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.\n\nYou can install Carthage with [Homebrew](http://brew.sh/) using the following command:\n\n```bash\n$ brew update\n$ brew install carthage\n```\n\nTo integrate PromisedFuture into your Xcode project using Carthage, specify it in your `Cartfile`:\n\n```ogdl\ngithub \"aladinway/PromisedFuture\"\n```\n\nRun `carthage update` to build the framework and on your application targets’ “General” settings tab, in the “Embedded Binaries” section, drag and drop the built `PromisedFuture.framework` from the Carthage/Build folder on disk.\n\n## Usage\n\n**Create a `Future`**:\n\nto create a `Future` using an operation (network call for example) we use:\n\n`init(operation: @escaping (_ completion:@escaping Completion) -\u003e Void)`\n\n  - Parameters:\n      - `operation`: the operation that should be performed by the Future. This is usually the asynchronous operation.\n      - `completion`: the completion block of the operation. It has the `Result` of the operation as parameter.\n  - Example usage:\n\n```swift\nlet future = Future(operation: { completion in\n// Your operation here to retrieve the value\nAlamofire.request(\"https://httpbin.org/get\")\n    .responseData { response in\n        switch response.result {\n        case .success(let value):\n\t\t// Then in case of success you call the completion\n\t\t// with the Result passing the value\n\t\tcompletion(.success(data))\n        case .failure(let error):\n\t\t// or in case of error call the completion\n\t\t// with the Result passing the error like :\n\t\t//completion(.failure(error))\n        }\n    }\n})\n```\n\nYou can also create a `Future` by `Result`, `Value` or `Error`.\n\nInitialize a new `Future` with the provided `Result`:\n\n`init(result: Result\u003cValue\u003e)` \n\n  - Parameters:\n      - `result`: The result of the `Future`. It can be a `Result` of success with a value or failure with an `Error`.\n \n  - Example usage:\n\n```swift\nlet future = Future(result: Result.success(12))\n```\n Initialize a new `Future` with the provided value:\n  \n`init(value: Value)` \n\n  - Parameters:\n      - `value`: The value of the `Future`.\n \n  - Example usage:\n\n```swift\nlet future = Future(value: \"Hello\")\n```\n \nInitialize a new `Future` with the provided `Error`:\n  \n`init(value: Value)` \n\n  - Parameters:\n      - `value`: The value of the `Future`.\n \n  - Example usage:\n\n```swift\nlet f: Future\u003cInt\u003e= Future(error: NSError(domain: \"E\", code: 4, userInfo: nil))\n```\n \n**Execute a `Future`**:\n \n To execute the operation of the Future we can use one these methods:\n \n - `func execute(completion: @escaping Completion)`\n\n   - Parameters:\n      - `completion`: the completion block of the operation. It has the `Result` of the operation as parameter.\n \n  - Example usage:\n\n\t```swift\n     let future = Future(value: 14)\n     future.execute(completion: { result in\n        switch result {\n        case .success(let value):\n            print(value) // it will print 14\n        case .failure(let error):\n            print(error)\n        }\n     })\n\t```\n  \n - `func execute(completion: @escaping Completion)`\n\n   - Parameters:\n       - `onSuccess`: the success completion block of the operation. It has the value of the operation as parameter.\n       - `onFailure`: the failure completion block of the operation. It has the error of the operation as parameter.\n \n  - Example usage:\n\n\t```swift\n     let future = Future(value: 14)\n     future.execute(onSuccess: { value in\n        print(value) // it will print 14\n     }, onFailure: { error in\n        print(error)\n     })\n\t```\n \n**Chaining multiple `Future`**:\n \n The powerful part of the Future is the ability to chain asynchronous operations.  We can use `andThen` method to chain two depending futures.\n \n - `func andThen\u003cU\u003e(_ f: @escaping (_ value: Value) -\u003e Future\u003cU\u003e) -\u003e Future\u003cU\u003e`\n\n   - Parameters:\n       - `f`: function that will generate a new `Future` by passing the value of this Future.\n \n  - Example usage:\n\n\t```swift\n     struct User {\n        id: Int\n     }\n\n     // Let's assume we need to perform two network operations\n     // The first one to get the user id\n     // And the second one to get the user information\n     // we can use `andThen` to chain them\n\n     let userIdFuture = Future(value: 14)\n\n     func userFuture(by userId: Int) -\u003e Future\u003cUser\u003e {\n        return Future(value: User(id: userId))\n     }\n\n     userIdFuture.andThen(userFuture).execute { user in\n        print(user)\n     }\n\t```\n\t\n\tWe can also map the result of the `Future` using `map` function:\n\t\n\t - `func map\u003cT\u003e(_ f: @escaping (_ value: Value) -\u003e T) -\u003e Future\u003cT\u003e`\n\n   - Parameters:\n       - `f`: function that will generate a new `Future` by passing the value of this Future\n \n  - Example usage:\n\n\t```swift\n     let stringFuture = Future(value: \"http://www.google.com\")\n     let urlFuture = stringFuture.map({URL(string: $0)})\n\t```\n \n## Reading\n\nI highly recommend reading my article below, If you want to learn more about `Futures` and how we can use **PromisedFuture** in the networking layer with `Alamofire` : \n\n[Write a Networking Layer in Swift 4 using Alamofire 5 and Codable Part 3: Using Futures/Promises](https://medium.com/@AladinWay/write-a-networking-layer-in-swift-4-using-alamofire-5-and-codable-part-3-using-futures-promises-cf3977fc8a5)\n\n \n## Author\n\nAlaeddine Messaoudi \u003citechnodev@gmail.com\u003e\n\n## License\n\nPromisedFuture is available under the MIT license. See the LICENSE file for more info.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faladinway%2Fpromisedfuture","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faladinway%2Fpromisedfuture","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faladinway%2Fpromisedfuture/lists"}