Guide · Open source
How to use PromiseKit: install, chain async steps and handle errors
Updated · written with AI from the project's own documentation and checked against our catalogue data
PromiseKit is an MIT-licensed library for Swift and Objective-C that lets you run asynchronous work, such as network requests or location lookups, as a readable chain of steps instead of nested callbacks. This guide shows how to install it with CocoaPods, read a promise chain, use the Apple API extensions and handle errors. It assumes you already work with Xcode and a dependency manager.
Quick start
- 1Add the pod. Open your Podfile and add pod "PromiseKit", "~> 8" inside your app target, with use_frameworks! at the top.
- 2Install dependencies. Run CocoaPods to install PromiseKit into your project and open the generated workspace in Xcode.
- 3Import PromiseKit. Import PromiseKit in the Swift or Objective-C files where you need promises.
- 4Wrap an async call. Start a chain with firstly and return a promise from an asynchronous operation such as URLSession.dataTask.
- 5Add done and catch. Use done to handle the result and catch to handle errors from any earlier step.
- 6Add extensions if needed. Add subspecs such as PromiseKit/CoreLocation to your Podfile for the Apple APIs you use.
What does PromiseKit do?
PromiseKit lets you express asynchronous operations as promises and chain them together. The README describes the result as clearer, more readable code than nested callbacks.
The library is aimed at iOS and macOS developers, and the README also lists tvOS, watchOS, Linux and Android as supported platforms in its older-version notes.
Install PromiseKit with CocoaPods
The README's quick start uses CocoaPods. Add the pod to your Podfile inside your app target. The README's example uses a placeholder target name, which you should replace with your own.
PromiseKit 8 supports recent Xcode versions (13 and newer, per the README).
- Add use_frameworks! to the Podfile if it is not already there.
- Add the PromiseKit pod inside your target block, pinned to version 8 with the ~> operator.
use_frameworks!
target "Change Me!" do
pod "PromiseKit", "~> 8"
endChain asynchronous steps with firstly, done and catch
A chain starts with firstly, which wraps the first asynchronous operation. Each following step runs when the previous one finishes. The done step receives the result, ensure runs whether the chain succeeded or failed, and catch handles any error from earlier steps.
The README example combines two requests with when(fulfilled:), which waits for both promises before the done step runs. Here, fetchImage and fetchLocation are promises defined earlier in the same snippet.
- firstly: starts the chain with the first operation.
- when(fulfilled:): waits for several promises to all succeed.
- done: receives the final values and does not return a new promise.
- ensure: runs cleanup code regardless of the outcome.
- catch: handles errors from any earlier step.
firstly {
when(fulfilled: fetchImage, fetchLocation)
}.done { image, location in
self.imageView.image = image
self.label.text = "\(location)"
}.ensure {
UIApplication.shared.isNetworkActivityIndicatorVisible = false
}.catch { error in
self.show(UIAlertController(for: error), sender: self)
}Use the Apple API extensions
PromiseKit includes extensions that wrap many of Apple's asynchronous APIs as promises. The default CocoaPod provides the core promises plus extensions for Foundation and UIKit. Other extensions are added as subspecs in your Podfile, such as MapKit and CoreLocation.
If you do not want the extensions, the README shows how to install only the core with the CorePromise subspec. Carthage installations come with no extensions by default.
- Default pod: core promises plus Foundation and UIKit extensions.
- Subspecs such as PromiseKit/MapKit or PromiseKit/CoreLocation add more Apple APIs.
pod "PromiseKit/MapKit" # MKDirections().calculate().then { /*…*/ }
pod "PromiseKit/CoreLocation" # CLLocationManager.requestLocation().then { /*…*/ }Make a network request as a promise
Promise chains often begin with a network call. The README shows URLSession wrapped with a dataTask promise and a .validate() call, which turns responses such as 404s into errors. The Foundation extension is listed as a separate pod in the example comment.
The example builds a POST request with JSON headers and body, then decodes the response. The helper function makeUrlRequest and the types Foo and obj are placeholders you would define in your own code.
firstly {
URLSession.shared.dataTask(.promise, with: try makeUrlRequest()).validate()
// ^^ we provide `.validate()` so that eg. 404s get converted to errors
}.map {
try JSONDecoder().decode(Foo.self, with: $0.data)
}.done { foo in
//…
}.catch { error in
//…
}Where to find more help
The README links to a Handbook with Getting Started and Common Patterns guides, a Manual with an Installation Guide, Objective-C Guide and Troubleshooting page, and an API reference. For questions not covered there, the README points to a Gitter chat channel and the bug tracker.
- Getting Started and Common Patterns guides in the Handbook.
- Troubleshooting for common compile errors.
- Installation Guide for Carthage, SwiftPM and older Swift or Xcode versions.
What people use it for
- Chaining a network request, JSON decoding and UI update in one readable sequence.
- Waiting for an image download and a location lookup with when(fulfilled:) before updating the screen.
- Converting HTTP error responses into thrown errors with .validate().
- Wrapping Apple APIs such as CoreLocation or MapKit directions as promises.
- Keeping an Objective-C codebase on promise-style APIs.
Frequently asked questions
Is PromiseKit free to use?
PromiseKit is released under the MIT licence, as stated on its repository page. The README also mentions a separate paid TideLift support offering, which is optional.
How do I install PromiseKit?
The README's quick start installs it with CocoaPods by adding pod "PromiseKit", "~> 8" to your Podfile. Carthage and Swift Package Manager are also mentioned, and the Installation Guide covers them.
What do I need to use PromiseKit 8?
The README says PromiseKit 8 supports recent Xcode versions, 13 and newer. You also need a dependency manager such as CocoaPods, Carthage or Swift Package Manager.
Should I use PromiseKit or async/await?
The README says Swift 5.5 and later include built-in async/await, and points to Async+ as a port of PromiseKit's patterns for that style. New projects on modern Swift may prefer built-in concurrency.
Does PromiseKit work with Objective-C?
Yes. The README describes its Objective-C bridging as a core strength and links an Objective-C Guide in the Manual.
Where can I get help if something breaks?
Check the Troubleshooting Guide first, which covers common compile errors. If that does not solve it, the README points to the Gitter chat channel and the bug tracker.
New agent skills, repos and AI tools — every week
The best new skills and open-source projects, the fastest-growing repos, and one free prompt. Five minutes to read. Unsubscribe anytime.
Our verdict
PromiseKit suits iOS or macOS developers who chain several asynchronous operations, maintain Objective-C code, or still use CocoaPods, Carthage or SwiftPM with older Xcode versions. If you are writing new code on Swift 5.5 or later and want built-in concurrency, the README points you to async/await or the Async+ port instead, and a single callback rarely needs a promise library.
Install options & downloads