Elegant Async code for Swift
fetchUserId().then { id in
print("UserID : \(id)")
}.onError { e in
print("An error occured : \(e)")
}.finally {
print("Everything is Done :)")
}
fetchUserId({ id in
fetchUserNameFromId(id, success: { name in
fetchUserFollowStatusFromName(name, success: { isFollowed in
// The three calls in a row succeeded YAY!
reloadList()
}, failure: { error in
// Fetching user ID failed
reloadList()
})
}, failure: { error in
// Fetching user name failed
reloadList()
})
}) { error in
// Fetching user follow status failed
reloadList()
}
๐๐๐#callbackHell
fetchUserId()
.then(fetchUserNameFromId)
.then(fetchUserFollowStatusFromName)
.then(updateFollowStatus)
.onError(showErrorPopup)
.finally(reloadList)
Because async code is hard to write, hard to read, hard to reason about.
A pain to maintain
By using a then keyword that enables you to write aSync code that reads like an English sentence
Async code is now concise, flexible and maintainable โค๏ธ
- Based on the popular Promise/Future concept
- Lightweight (1 file ~100lines)
- Pure Swift
- No magic involved
- Strongly Typed
- Chainable
pod 'thenPromise'
use_frameworks!
github "s4cha/then"
Simply Copy and Paste Promise.swift in your Xcode Project :) https://github.com/s4cha/then/blob/master/Code/then/Promise.swift
Grab this repository and build the Framework target on the example project. Then Link against this framework.
fetchUserId().then { id in
print("UserID : \(id)")
}.onError { e in
print("An error occured : \(e)")
}.finally {
print("Everything is Done :)")
}
If we want this to be maintainable, it should read like an English sentence
We can do this by extracting our blocks into separate functions:
fetchUserId()
.then(printUserID)
.onError(showErrorPopup)
.finally(reloadList)
This is now concise, flexible, maintainable, and it reads like an English sentence <3
Mental sanity saved
// #goodbyeCallbackHell
Wondering what fetchUserId() is?
It is a simple function that returns a strongly typed promise :
func fetchUserId() -> Promise<Int> {
return Promise { resolve, reject in
print("fetching user Id ...")
wait { resolve(object: 1234) }
}
}
Here you would typically replace the dummy wait function by your network request <3
S4cha, YannickDot, Damien, piterlouis
then is part of a series of lightweight libraries aiming to make developing iOS Apps a breeze: