Skip to content
This repository has been archived by the owner on Feb 28, 2020. It is now read-only.

Commit

Permalink
Merge branch 'release/1.1.3'
Browse files Browse the repository at this point in the history
  • Loading branch information
vmartinelli committed Sep 5, 2015
2 parents d64d341 + 8a44f5c commit 674aa41
Show file tree
Hide file tree
Showing 11 changed files with 102 additions and 35 deletions.
2 changes: 1 addition & 1 deletion AlecrimAsyncKit.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|

s.name = "AlecrimAsyncKit"
s.version = "1.1.2"
s.version = "1.1.3"
s.summary = "Bringing async and await to Swift world with some flavouring."
s.homepage = "https://github.com/Alecrim/AlecrimAsyncKit"

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ Since a task is started when it is created it can only be cancelled after runnin

To cancel a task you use `asyncEx` method to create it and use the `cancel` method of `Task<T>` class.

To cancel a task is the same as finishing it with a `NSError` with `NSCocoaErrorDomain` domain and `NSUserCancelledError` code.
To cancel a task is the same as finishing it with a `NSError` with `NSUserCancelledError` code.

If you want to use task cancellation you'll have check inside the task body closure for the `cancelled` property to stop any work the task are doing as soon it is cancelled.

Expand Down
8 changes: 6 additions & 2 deletions Source/AlecrimAsyncKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
/* Begin PBXBuildFile section */
140A15081B7FA79D0028DBCE /* AsyncAwait.swift in Sources */ = {isa = PBXBuildFile; fileRef = 140A15041B7FA79D0028DBCE /* AsyncAwait.swift */; };
140A15091B7FA79D0028DBCE /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = 140A15051B7FA79D0028DBCE /* Task.swift */; };
141067E81B9B75AA0030AABB /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 141067E71B9B75AA0030AABB /* Errors.swift */; settings = {ASSET_TAGS = (); }; };
14B139901B88824F00131B01 /* TaskCondition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 140A15061B7FA79D0028DBCE /* TaskCondition.swift */; };
14B139911B8889DA00131B01 /* SilentTaskCondition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 148F1DFA1B7FAA7B0026C36D /* SilentTaskCondition.swift */; };
14B139921B8889DA00131B01 /* NegateTaskCondition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 148F1DFC1B7FAE800026C36D /* NegateTaskCondition.swift */; };
Expand All @@ -25,6 +26,7 @@
140A15051B7FA79D0028DBCE /* Task.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Task.swift; sourceTree = "<group>"; };
140A15061B7FA79D0028DBCE /* TaskCondition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TaskCondition.swift; sourceTree = "<group>"; };
140A15071B7FA79D0028DBCE /* TaskObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TaskObserver.swift; sourceTree = "<group>"; };
141067E71B9B75AA0030AABB /* Errors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Errors.swift; sourceTree = "<group>"; };
142E25E91B7FBF4200B6C952 /* TimeoutTaskObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimeoutTaskObserver.swift; sourceTree = "<group>"; };
142E25EB1B7FC58A00B6C952 /* NetworkActivityTaskObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkActivityTaskObserver.swift; sourceTree = "<group>"; };
148F1DFA1B7FAA7B0026C36D /* SilentTaskCondition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SilentTaskCondition.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -54,6 +56,7 @@
140A15051B7FA79D0028DBCE /* Task.swift */,
140A15061B7FA79D0028DBCE /* TaskCondition.swift */,
140A15071B7FA79D0028DBCE /* TaskObserver.swift */,
141067E71B9B75AA0030AABB /* Errors.swift */,
);
path = Core;
sourceTree = "<group>";
Expand Down Expand Up @@ -205,6 +208,7 @@
14B139951B888B7700131B01 /* TaskObserver.swift in Sources */,
14B139921B8889DA00131B01 /* NegateTaskCondition.swift in Sources */,
14B139941B8889DA00131B01 /* MutuallyExclusiveTaskCondition.swift in Sources */,
141067E81B9B75AA0030AABB /* Errors.swift in Sources */,
14B139971B888E1600131B01 /* NetworkActivityTaskObserver.swift in Sources */,
140A15091B7FA79D0028DBCE /* Task.swift in Sources */,
14B139931B8889DA00131B01 /* DelayTaskCondition.swift in Sources */,
Expand Down Expand Up @@ -317,7 +321,7 @@
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 83;
CURRENT_PROJECT_VERSION = 87;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
Expand All @@ -339,7 +343,7 @@
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 83;
CURRENT_PROJECT_VERSION = 87;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Foundation
public final class DelayTaskCondition: TaskCondition {

public init(timeInterval: NSTimeInterval, tolerance: NSTimeInterval = 0) {
super.init(subconditions: nil, dependencyTask: nil) { result in
super.init() { result in
let queue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL)
let timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public final class MutuallyExclusiveTaskCondition: TaskCondition {
public init(_ categoryName: String) {
self.categoryName = categoryName

super.init(subconditions: nil, dependencyTask: nil) { result in
super.init() { result in
result(.Satisfied)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,14 @@ import Foundation
public final class NegateTaskCondition: TaskCondition {

public init(_ otherCondition: TaskCondition) {
super.init(subconditions: otherCondition.subconditions, dependencyTask: otherCondition.dependencyTask, evaluationClosure: otherCondition.evaluationClosure)
super.init(subconditions: otherCondition.subconditions, dependencyTask: otherCondition.dependencyTaskClosure(), evaluationClosure: otherCondition.evaluationClosure)
}

internal override func asyncEvaluate() -> Task<Void> {
return asyncEx { task in
do {
try await(super.asyncEvaluate())

let error = NSError(domain: "com.alecrim.AlecrimAsyncKit.NegateTaskCondition", code: 1000, userInfo: nil)
task.finishWithError(error)
task.finishWithError(TaskConditionError.NotSatisfied)
}
catch {
task.finish()
Expand Down
20 changes: 20 additions & 0 deletions Source/AlecrimAsyncKit/Core/AsyncAwait.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,26 @@ public func asyncEx<V>(queue: NSOperationQueue = _defaultTaskQueue, observers: [

//

@warn_unused_result
public func async<V>(queue: NSOperationQueue = _defaultTaskQueue, condition: TaskCondition, observers: [TaskObserver], closure: () throws -> V) -> Task<V> {
return Task<V>(queue: queue, observers: observers, conditions: [condition]) { (task: Task<V>) -> Void in
do {
let value = try closure()
task.finishWithValue(value)
}
catch let error {
task.finishWithError(error)
}
}
}

@warn_unused_result
public func asyncEx<V>(queue: NSOperationQueue = _defaultTaskQueue, condition: TaskCondition, observers: [TaskObserver], closure: (Task<V>) -> Void) -> Task<V> {
return Task<V>(queue: queue, observers: observers, conditions: [condition], closure: closure)
}

//

@warn_unused_result
public func async<V>(queue: NSOperationQueue = _defaultTaskQueue, conditions: [TaskCondition], observers: [TaskObserver], closure: () throws -> V) -> Task<V> {
return Task<V>(queue: queue, observers: observers, conditions: conditions) { (task: Task<V>) -> Void in
Expand Down
30 changes: 30 additions & 0 deletions Source/AlecrimAsyncKit/Core/Errors.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// Errors.swift
// AlecrimAsyncKit
//
// Created by Vanderlei Martinelli on 2015-09-05.
// Copyright © 2015 Alecrim. All rights reserved.
//

import Foundation

// MARK: -

public enum TaskConditionError: ErrorType {
case NotSatisfied
case ExecutionFailed(innerError: ErrorType)
}

// MARK: -

internal let taskCancelledError = NSError(code: NSUserCancelledError)

// MARK: -

extension NSError {

private convenience init(code: Int, userInfo dict: [NSObject : AnyObject]? = nil) {
self.init(domain: "com.alecrim.AlecrimAsyncKit", code: code, userInfo: dict)
}

}
8 changes: 6 additions & 2 deletions Source/AlecrimAsyncKit/Core/Task.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@

import Foundation

internal let taskCancelledError = NSError(domain: NSCocoaErrorDomain, code: NSUserCancelledError, userInfo: nil)

// MARK: - protocols needed to support task observers in this version

public protocol TaskType: class {
Expand Down Expand Up @@ -166,6 +164,12 @@ public final class Task<V>: BaseTask<V>, FailableTaskType {
//
closure(self)
}
catch TaskConditionError.NotSatisfied {
self.cancel()
}
catch TaskConditionError.ExecutionFailed(let innerError) {
self.finishWithError(innerError)
}
catch let error {
self.finishWithError(error)
}
Expand Down
55 changes: 33 additions & 22 deletions Source/AlecrimAsyncKit/Core/TaskCondition.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,55 +20,65 @@ private let _defaultTaskConditionQueue: NSOperationQueue = {

public enum TaskConditionResult {
case Satisfied
case Failed
case FailedWithError(ErrorType)
case NotSatisfied
case ExecutionFailed(error: ErrorType)
}


public class TaskCondition {

internal let subconditions: [TaskCondition]?
internal let dependencyTask: Task<Void>?
internal let dependencyTaskClosure: () -> Task<Void>?
internal let evaluationClosure: ((TaskConditionResult) -> Void) -> Void

public convenience init(evaluationClosure: ((TaskConditionResult) -> Void) -> Void) {
self.init(subconditions: nil, dependencyTask: nil, evaluationClosure: evaluationClosure)
public init(evaluationClosure: ((TaskConditionResult) -> Void) -> Void) {
self.subconditions = nil
self.dependencyTaskClosure = { return nil }
self.evaluationClosure = evaluationClosure
}

public convenience init(dependencyTask: Task<Void>, evaluationClosure: ((TaskConditionResult) -> Void) -> Void) {
self.init(subconditions: nil, dependencyTask: dependencyTask, evaluationClosure: evaluationClosure)
public init(@autoclosure(escaping) dependencyTask dependencyTaskClosure: () -> Task<Void>?, evaluationClosure: ((TaskConditionResult) -> Void) -> Void) {
self.subconditions = nil
self.dependencyTaskClosure = dependencyTaskClosure
self.evaluationClosure = evaluationClosure
}

public convenience init(subcondition: TaskCondition, evaluationClosure: ((TaskConditionResult) -> Void) -> Void) {
self.init(subconditions: [subcondition], dependencyTask: nil, evaluationClosure: evaluationClosure)
public init(subcondition: TaskCondition, evaluationClosure: ((TaskConditionResult) -> Void) -> Void) {
self.subconditions = [subcondition]
self.dependencyTaskClosure = { return nil }
self.evaluationClosure = evaluationClosure
}

public convenience init(subcondition: TaskCondition, dependencyTask: Task<Void>, evaluationClosure: ((TaskConditionResult) -> Void) -> Void) {
self.init(subconditions: [subcondition], dependencyTask: dependencyTask, evaluationClosure: evaluationClosure)
public init(subcondition: TaskCondition, @autoclosure(escaping) dependencyTask dependencyTaskClosure: () -> Task<Void>?, evaluationClosure: ((TaskConditionResult) -> Void) -> Void) {
self.subconditions = [subcondition]
self.dependencyTaskClosure = dependencyTaskClosure
self.evaluationClosure = evaluationClosure
}

public convenience init(subconditions: [TaskCondition], evaluationClosure: ((TaskConditionResult) -> Void) -> Void) {
self.init(subconditions: subconditions, dependencyTask: nil, evaluationClosure: evaluationClosure)
public init(subconditions: [TaskCondition], evaluationClosure: ((TaskConditionResult) -> Void) -> Void) {
self.subconditions = subconditions
self.dependencyTaskClosure = { return nil }
self.evaluationClosure = evaluationClosure
}

public init(subconditions: [TaskCondition]?, dependencyTask: Task<Void>?, evaluationClosure: ((TaskConditionResult) -> Void) -> Void) {
public init(subconditions: [TaskCondition]?, @autoclosure(escaping) dependencyTask dependencyTaskClosure: () -> Task<Void>?, evaluationClosure: ((TaskConditionResult) -> Void) -> Void) {
self.subconditions = subconditions
self.dependencyTask = dependencyTask
self.dependencyTaskClosure = dependencyTaskClosure
self.evaluationClosure = evaluationClosure
}

internal func asyncEvaluate() -> Task<Void> {
return asyncEx(_defaultTaskConditionQueue) { [unowned self] task in
self.evaluationClosure { conditionResult in
switch conditionResult {
case .Satisfied:
task.finish()

case .Failed:
task.finishWithError(taskCancelledError)
case .NotSatisfied:
task.finishWithError(TaskConditionError.NotSatisfied)

case .FailedWithError(let error):
task.finishWithError(error)
case .ExecutionFailed(let error):
task.finishWithError(TaskConditionError.ExecutionFailed(innerError: error))
}
}
}
Expand All @@ -81,11 +91,11 @@ extension TaskCondition {
internal static func asyncEvaluateConditions(conditions: [TaskCondition]) -> Task<Void> {
return async(_defaultTaskConditionQueue) {
for condition in conditions {
if let subconditions = condition.subconditions {
if let subconditions = condition.subconditions where !subconditions.isEmpty {
try await(TaskCondition.asyncEvaluateConditions(subconditions))
}

if let dependencyTask = condition.dependencyTask {
if let dependencyTask = condition.dependencyTaskClosure() {
try await(dependencyTask)
}

Expand All @@ -95,3 +105,4 @@ extension TaskCondition {
}

}

2 changes: 1 addition & 1 deletion Source/AlecrimAsyncKit/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.1.2</string>
<string>1.1.3</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
Expand Down

0 comments on commit 674aa41

Please sign in to comment.