Skip to content

nghialv/Future

Repository files navigation

Future

Language CocoaPods [Carthage compatible] (https://github.com/Carthage/Carthage) License Issues

Swift µframework providing Future<T, Error>.

This library is inspired by the talk of Javier Soto at SwiftSubmit2015 and the Future implementation in Scala.

And this is using antitypical/Result.

Why we need Future?

Traditional async code
 func requestRepository(repoId: Int64, completion: (Repository?, NSError?) -> Void) {}
 func requestUser(userId: Int64, completion: (User?, NSError?) -> Void) {}
 
 // get owner info of a given repository
 requestRepository(12345) { repo, error in
 	if let repo = repo {
 		requestUser(repo.ownerId) { user, error in
 		   if let user = user {
 		       // do something
 		   } else {
 		       // error handling
 		   }
 		}
 	} else {
 		// error handling
 	}
 }
 
Code with Future
let future = requestRepository(12345)
		.map { $0.ownerId }
		.flatMap(requestUser)

future.onCompleted { result in
	switch result {
		case .Success(let user):   println(user)
		case .Failure(let error):  println(error)
	}
}

Shorthand by using operator

let future = requestRepository(12345) <^> { $0.ownerId } >>- requestUser

future.onCompleted { result in
	switch result {
		case .Success(let user):   println(user)
		case .Failure(let error):  println(error)
	}
}

Usage

  • map <^>
let f = requestUser("nghialv") <^> { $0.id }

f.onSuccess { userId in
	println(userId)
}
  • flatMap >>-
let f = searchRepositories("Hakuba") <^> { $0.first!.ownerName } >>- requestUser

f.onComplete { result in
	switch result {
		case .Success(let user):   println(user)
		case .Failure(let error):  println(error)
	}
}
  • filter
let e = NSError(domain: "noSuchElement", code: 1, userInfo: nil)
let f1 = searchRepositories("Hakuba")

let f = f1.filter(e){ $0.count > 0 } <^> { $0.first!.ownerName } >>- requestUser

f.onComplete { result in
	switch result {
		case .Success(let user):   println(user)
		case .Failure(let error):  println(error)
	}
}
  • andThen
// side-effect
var reposCount = 0
        
let f1 = searchRepositories("Hakuba")
let f2 = f1.andThen { result in
    switch result {
        case .Success(let repos): reposCount = repos.value.count
        case .Failure(let error): break
    }
}
let f3 = f2 <^> { $0.first!.ownerName } >>- requestUser
        
f3.onComplete { result in
    switch result {
        case .Success(let user):   println(user)
        case .Failure(let error):  println(error)
    }
}
  • recover

  • zip

let f1 = searchRepositories("Future")
let f2 = requestUser("nghialv")
        
let f3 = f1.zip(f2)

f3.onSuccess { repos, user in
	println(repos)
	println(user)
}
  • flatten

Installation

  • Using Carthage
  • Insert github "nghialv/Future" to your Cartfile
  • Run carthage update
  • Using Cocoapods
  • Insert use_frameworks! to your Podfile
  • Insert pod "Future" to your Podfile
  • Run pod install
  • Using Submodule

Requirements

  • Swift 1.2 (Xcode 6.3 or later)
  • iOS 8.0 or later