krzyzanowskim /
CryptoSwift
CryptoSwift is a growing collection of standard and secure cryptographic algorithms implemented in Swift
Loading repository data…
troystribling / repository
Swift implementation of Scala Futures http://docs.scala-lang.org/overviews/core/futures.html

A Swift implementation of Scala Futures with extras.
Futures provide an interface for performing nonblocking asynchronous requests and combinator interfaces for serializing the processing of requests, error recovery and filtering. In most iOS libraries asynchronous interfaces are supported through the delegate-protocol pattern or with a callback. Even simple implementations of these interfaces can lead to business logic distributed over many files or deeply nested callbacks that can be hard to follow.
SimpleFutures is an implementation of Scala Futures in Swift and was influenced by BrightFutures.
CocoaPods is an Xcode dependency manager. It is installed with the following command,
gem install cocoapods
Requires CocoaPods 1.1+
Add SimpleFutures to your to your project Podfile,
platform :ios, '9.0'
use_frameworks!
target 'Your Target Name' do
pod 'SimpleFutures', '~> 0.2'
end
To enable DBUG output add this post_install hook to your Podfile
Carthage is a decentralized dependency manager for Xcode projects. It can be installed using Homebrew,
brew update
brew install carthage
To add SimpleFutures to your Cartfile
github "troystribling/SimpleFutures" ~> 0.2
To download and build SimpleFutures.framework run the command,
carthage update
then add SimpleFutures.framework to your project.
If desired use the --no-build option,
carthage update --no-build
This will only download SimpleFutures. Then follow the steps in Manual to add it to a project.
git submodule.Another option is to add SimpleFutures.swift directly to your project, since the entire library is contained in a single file.
A simple wrapper around GCD is provided.
// create a queue with .background pos
let queue = Queue("us.gnos.myqueue")
// run block synchronously on queue
queue.sync {
// do something
}
// return a value from a synchronous task
let result = queue.sync {
// do something
return value
}
// run block asynchronously on queue
queue.async {
// do something
}
// run block asynchronously at specified number of seconds from now
queue.delay(10.0) {
// do something
}
An ExecutionContext executes tasks and is defined by an implementation of the protocol,
public protocol ExecutionContext {
func execute(task: Void -> Void)
}
SimpleFutures provides a QueueContext which runs tasks asynchronously on a specified Queue and ImmediateContext which executes task synchronously on the calling thread.
// main and global queue contexts
QueueContext.main
QueueContext.global
// create a QueueContext using queue
public init(queue: Queue)
// immediate context runs tasks synchronously on the calling thread
ImmediateContext()
Completion handlers and combinators for both Futures and FutureStreams run within a specified context. The default context is QueueContext.main
ImmediateContext() can be useful for testing.
A Future instance is a read-only encapsulation of an immutable result that can be computed anytime in the future. When the result is computed the Future is said to be completed. A Future may be completed successfully with a value or failed with an error.
A Future also has combinator methods that allow multiple instances to be chained together and executed serially and container methods are provided that can evaluate multiple Futures simultaneously.
A Future can be created using either the future method, a Promise or initializer.
initinit methods are provided that create a Future<T> with a specified result.
// create an uncompleted future
public init()
// create a future with result of type T
public init(value: T)
// create a Future with an error result
public init(error: Swift.Error)
futureSeveral versions of future are provided to facilitate integration with existing code.
The simplest take a synchronous @autoclosure or closure,
// task is executed synchronously
public func future<T>( _ task: @autoclosure @escaping (Void) -> T) -> Future<T>
// task is executed in context which may be asynchronous
public func future<T>(context: ExecutionContext = QueueContext.futuresDefault, _ task: @escaping (Void) throws -> T) -> Future<T>
Versions that take an asynchronous closure parameter of common completion block types are also provided.
public func future<T>(method: (@escaping (T, Swift.Error?) -> Void) -> Void) -> Future<T>
public func future<T>(method: (@escaping (T, Swift.Error?) -> Void) -> Void) -> Future<T>
public func future<T>(method: (@escaping (T) -> Void) -> Void) -> Future<T>
Adding a Future interface to existing code is simple using future. Consider the following class with an asynchronous request taking a completion block,
class AsyncRequester {
func request(completion: @escaping (Int?, Swift.Error?) -> Void)
}
An extension adding a Future interface would look like,
extension AsyncRequester {
func futureRequest() -> Future<Int?> {
return future(method: request)
}
}
PromiseA Promise instance is one-time writable and contains a Future. When completing its Future successfully a Promise will write a value to the Future result and when completing with failure will write an error to its Future result.
// Create and uncompleted Promise
public init()
// Completed Promise with another Future
public func completeWith(context: ExecutionContext = QueueContext.futuresDefault, future: Future<T>)
// Complete Promise successfully with value
public func success(_ value: T)
// Complete Promise with error
public func failure(_ error: Swift.Error)
Future interface implementations can use a Promise to create and manage the Future.
Here a simple URLSession extension is shown that adds a method performing an HTTP GET request returning a Future.
extension URLSession {
class func get(with url: URL) -> Future<(Data?, URLResponse?)> {
let promise = Promise<(Data?, URLResponse?)>()
let session = URLSession.shared
let task = session.dataTask(with: url) { (data, response, error) in
if let error = error {
promise.failure(error)
} else {
promise.success((data, response))
}
}
task.resume()
return promise.future
}
}
To use in an application,
let requestFuture = URLSession.get(with: URL(string: "http://troystribling.com")!)
Setting the value of a Future result completes it. The holder of a Future reference is notified of completion by the methods onSuccess and onFailure. The requestFuture of the previous section would handle completion events using,
requestFuture.onSuccess { (data, response) in
guard let response = response, let data = data else {
return
}
// process data
}
requestFuture.onFailure { error in
// handle error
}
Multiple completion handlers can be defined for a single Future.
A Future can be completed with result of another Future using completeWith.
public func completeWith(context: ExecutionContext = QueueContext.futuresDefault, future: Future<T>)
For example,
let anotherFuture = Future<Int>()
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
let dependentFuture = future(method: asyncRequest)
anotherFuture.completeWith(future: dependentFuture)
Combinators are methods used to construct a serialized chain of Futures that perform asynchronous requests and apply mappings and filters to request results.
Apply a mapping: (T) throws -> M to the result of a successful Future<T> to produce a new Future<M>.
public func map<M>(context: ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToken = CancelToken(), mapping: @escaping (T) throws -> M) -> Future<M>
For example,
enum AppError: Error {
case invalidValue
}
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
let mappedFuture = future(method: asyncRequest).map { value -> String in
guard value < 0 else {
throw AppError.invalidValue
}
return "\(value)"
}
Apply a mapping: (T) throws -> Future<M> to the result of a successful Future<T> returning Future<M>. flatMap is used to serialize asynchronous requests.
public func flatMap<M>(context: ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToken = CancelToken(), mapping: @escaping (T) throws -> Future<M>) -> Future<M>
For example,
enum AppError: Error {
case invalidValue
}
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
func asyncMapping(Int) -> Future<String>
let mappedFuture = future(method: asyncRequest).flatMap { value -> Future<String> in
guard value < 0 else {
throw AppError.invalidValue
}
return asyncMapping(value)
}
flatMap will usually require specification of the closure return type. It is an overloaded method and the compiler sometimes needs help in determining which to use.
Apply a filter: (T) throws -> Bool to the result of a successful Future<T> returning the Future<T> if the filter succeeds and throwing FuturesError.noSuchElement if the filter fails.
public func withFilter(context: ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToke
Selected from shared topics, language and repository description—not editorial ratings.
krzyzanowskim /
CryptoSwift is a growing collection of standard and secure cryptographic algorithms implemented in Swift
newlinedotco /
swift implementation of flappy bird. More at fullstackedu.com
Yalantis /
KolodaView is a class designed to simplify the implementation of Tinder like cards on iOS.
SwiftWebUI /
A demo implementation of SwiftUI for the Web
Skyscanner /
A beautiful and flexible text field control implementation of "Float Label Pattern". Written in Swift.
Yalantis /
Our Guillotine Menu Transitioning Animation implemented in Swift reminds a bit of a notorious killing machine.