SwiftTaskLibrary
What is SwiftTaskLibrary
It is a Swift porting of the .net TPL. The purpose of the TPL is to make
developers more productive by simplifying the process of adding parallelism
and concurrency to applications.
Create a Task
A Task represents an asynchronous operation that is created and started by the means of the TaskFactory class.
The TaskFactoryclass implement the following methods:
startSync: Starts aTasksynchronouslystartAsync: Starts aTaskasynchronouslystartAfter: Starts aTaskasynchronously after the input number of milliseconds.
TaskFactory.startAsync(TaskScheduler.background()) {
return "Hello World!"
}
A continuation that executes asynchronously when the Task completes can be defined to the created Task.
let task = TaskFactory.startAsync(TaskScheduler.background()) {
return "Hello World!"
}
task.continueWith(TaskScheduler.ui()) {
[unowned self] task in
println(task.result ?? "NO RESULT")
}
Create a TaskCompletionSource
A TaskCompletionSource represents the producer side of a Task unbound to a delegate, providing access to the consumer side through the Task property.
It is a source for creating a task, and the source for that task’s completion. In essence, a TaskCompletionSource acts as the producer for a Task and its completion.
Using a TaskCompletionSource is quite handy when you don't have control of the asynchronus operation (for instance the operation is started by a third party library).
//Creates a new CancellationTokenSource
let cTokenSource = CancellationTokenSource()
//Defines a task continuation on the task created by the CancellationTokenSource
cTokenSource.task.continueWith(TaskScheduler.ui()) {
[unowned self] task in
println(task.result ?? "NO RESULT")
}
//Code that is not using `Task` to create the asynchronus operation
dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0)) {
println("TaskCompletionSource - Running")
sleep(5)
// Complete the task created by the CancellationTokenSource
tcs.setResult(self.getResult("TaskCompletionSource - Completed"))
}
Create asynchronous methods
Separation of the concerns reduce coupling and increase cohesion of the application.
An example of separation of concerns is the DAL (Data Access Layer).
The DAL is a layer which provided simplified access to data stored in persistent storage.
The DAL performs IO operations because of that Api must be asynchronous.
Below and exmaple of how an Api may look like.
Sample 1 - DataAccessLayer Protocol
public protocol DataAccessLayer {
func getOrders(success:([Order]) -> Void, failure:(NSError) -> Void))
}
In order to use the DataAccessLayer two closures have to passed in input.
Below an example of code which uses the DAL and perform an action on the UI thread once the asynchronous operation is completed.
Sample 2 - Usage of the DataAccessLayer
let dal = OrdersDataAccessLayer()
dal.getOrders({
orders in
dispatch_sync(dispatch_get_main_queue(), {
() -> Void in
update(orders)
})
},
failure: {
error in
dispatch_sync(dispatch_get_main_queue(), {
() -> Void in
log(error)
})
})
Using SwiftTaskLibrary the DAL code would be implemented as following.
Sample 3 - DataAccessLayer Protocol
public protocol DataAccessLayer {
func getOrdersAsync() -> Task<[Order]>
}
Sample 3 - Usage of the DataAccessLayer
let dal = OrdersDataAccessLayer()
dal.getOrdersAsync()
.continueWith(TaskScheduler.ui()) {
task in
if (task.isFaulted) {
log(task.error)
return
}
update(task.result)
}