I gave this talk at the CocoaHeadsNL meetup in April 2015. It gives an introduction to BrightFutures (https://github.com/Thomvis/BrightFutures), my open source futures & promises implementation in Swift.
fetchPosts(user: User) -> Future<[Post]> { } logIn(username,password).flatMap { user in fetchPosts(user) }.onSuccess { posts in // do something with the user's posts }.onFailure { error in // either logging in or fetching posts failed }
= user { fetchPostsWithCompletionHander(user) { posts, error in if let posts = posts { // hurray, do something with the posts } else if let error = error { // could not fetch posts, at least we have the user } else { // can this happen? } } } else if let error = error { // something went wrong } else { // can this happen? } }
[[String:Any]]) -> Result<[Product]> { ... } let productResult = jsonFromResponseData(data).flatMap { json in return parseProducts(json) } if let products = productResult.value { // do something with the products }
NSURLResponse!, NSError!) -> Void)? ) -> NSURLSessionDataTask // let's use it: session.dataTaskWithURL("http://bit.ly/1IPyYmP") { data, response, error in if error != nil { // something went wrong } else { // we can more or less safely use data and response now } }.resume()
{ jsonFromResponseData(data).flatMap { (json: [[String:Any]]) in return parseProducts(json) }.map { (products: [Product]) in for product in products { session.dataTaskWithURL(product.url) { result in // fetch something for each product }.resume() } // do something when all product.url's have been loaded? } } else { // something went wrong } }.resume()
}.flatMap { json in return parseProducts(json) }.flatMap { products: [Products] in return products.map { product in return dataFromURL(product.url).map { (data:NSData) in return (product, data) } } } sequence(res).onSuccess { (pd:[(Product, Data)]) in // do something with the products and their data }.onFailure { error in // something failed: // - retrieving bit.ly URL // - turning data into JSON // - turning JSON into products // - fetching additional data from the product's url }
}.flatMap { json in return parseProducts(json) }.flatMap { products: [Products] in return products.map { product in return dataFromURL(product.url).map { (data:NSData) in return (product, data) } } } sequence(res).onSuccess { (pd:[(Product, Data)]) in // do something with the products and their data }.onFailure { error in if let (product, data) = res.first?.value { // the first product did load, recover from the error by doing something with it } }
} let sumPrice = FutureUtils.fold(products, zero: 0) { sum, product in return sum + product.price } let token = InvalidationToken() Queue.global.after(.In(2.0)) { token.invalidate() } products.zip(sumPrice).map(context: Queue.global.context) { products, sumPrice in // we're on the global queue here return sumPrice / products.count }.onSuccess(token: token) { averagePrice in // safely update the UI label.setText(averagePrice) }