Skip to content
This repository has been archived by the owner on Oct 29, 2021. It is now read-only.

Commit

Permalink
Release 0.9.0
Browse files Browse the repository at this point in the history
  • Loading branch information
alexruperez committed Oct 26, 2017
1 parent a656c76 commit 3d573eb
Show file tree
Hide file tree
Showing 10 changed files with 180 additions and 129 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Release 0.9.0

- [x] Removed deprecated DispatchQueue methods and initializers.

# Release 0.8.1

- [x] Deprecated some DispatchQueue methods and initializers.
Expand Down
2 changes: 1 addition & 1 deletion Kommander.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'Kommander'
s.version = '0.8.1'
s.version = '0.9.0'
s.summary = 'A command pattern implementation written in Swift 4'

s.homepage = 'https://github.com/intelygenz/Kommander-iOS'
Expand Down
8 changes: 4 additions & 4 deletions Kommander.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -979,8 +979,8 @@
CURRENT_PROJECT_VERSION = "$(DYLIB_CURRENT_VERSION)";
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 3VW789WSMP;
DYLIB_COMPATIBILITY_VERSION = 0.8.0;
DYLIB_CURRENT_VERSION = 0.8.1;
DYLIB_COMPATIBILITY_VERSION = 0.9.0;
DYLIB_CURRENT_VERSION = 0.9.0;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
Expand Down Expand Up @@ -1051,8 +1051,8 @@
CURRENT_PROJECT_VERSION = "$(DYLIB_CURRENT_VERSION)";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = 3VW789WSMP;
DYLIB_COMPATIBILITY_VERSION = 0.8.0;
DYLIB_CURRENT_VERSION = 0.8.1;
DYLIB_COMPATIBILITY_VERSION = 0.9.0;
DYLIB_CURRENT_VERSION = 0.9.0;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
Expand Down
33 changes: 11 additions & 22 deletions KommanderTests/DispatcherTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class DispatcherTests: XCTestCase {

override func setUp() {
super.setUp()
dispatcher = Dispatcher()
dispatcher = .default
}

override func tearDown() {
Expand All @@ -42,7 +42,8 @@ class DispatcherTests: XCTestCase {
}

func testDefaultDispatcherDispatchQueue() {
let dispatchWorkItem = dispatcher.execute(qos: nil, flags: nil) { sleep(2) }
let dispatchWorkItem = DispatchWorkItem(qos: .default, flags: .assignCurrentContext) { sleep(2) }
dispatcher.execute(dispatchWorkItem)
XCTAssertFalse(dispatchWorkItem.isCancelled)
dispatchWorkItem.cancel()
XCTAssertTrue(dispatchWorkItem.isCancelled)
Expand All @@ -63,22 +64,8 @@ class DispatcherTests: XCTestCase {
}
}

func testCustomDispatcherDispatchQueue() {
let randomName = UUID().uuidString
dispatcher = Dispatcher(label: randomName, qos: .background, attributes: nil, autoreleaseFrequency: nil, target: nil)
XCTAssertEqual(dispatcher.dispatchQueue.label, randomName)
XCTAssertEqual(dispatcher.dispatchQueue.qos, .background)
if let dispatchWorkItem = dispatcher.execute({ sleep(2) }) as? DispatchWorkItem {
XCTAssertFalse(dispatchWorkItem.isCancelled)
dispatchWorkItem.cancel()
XCTAssertTrue(dispatchWorkItem.isCancelled)
} else {
XCTFail("Custom dispatcher isn't using DispatchQueue.")
}
}

func testMainDispatcherOperationQueue() {
dispatcher = MainDispatcher()
dispatcher = .main
if let operation = dispatcher.execute({ sleep(2) }) as? Operation {
XCTAssertEqual(dispatcher.operationQueue, OperationQueue.main)
XCTAssertGreaterThan(dispatcher.operationQueue.operationCount, 0)
Expand All @@ -90,8 +77,9 @@ class DispatcherTests: XCTestCase {
}

func testMainDispatcherDispatchQueue() {
dispatcher = MainDispatcher()
let dispatchWorkItem = dispatcher.execute(qos: nil, flags: nil, block: { sleep(2) })
dispatcher = .main
let dispatchWorkItem = DispatchWorkItem(qos: .default, flags: .assignCurrentContext) { sleep(2) }
dispatcher.execute(dispatchWorkItem)
XCTAssertEqual(dispatcher.dispatchQueue, DispatchQueue.main)
XCTAssertFalse(dispatchWorkItem.isCancelled)
dispatchWorkItem.cancel()
Expand All @@ -101,7 +89,7 @@ class DispatcherTests: XCTestCase {
func testCurrentDispatcherOperationQueue() {
let operationQueue = OperationQueue()
operationQueue.addOperation {
self.dispatcher = CurrentDispatcher()
self.dispatcher = .current
if let operation = self.dispatcher.execute({ sleep(2) }) as? Operation {
XCTAssertGreaterThan(self.dispatcher.operationQueue.operationCount, 0)
operation.cancel()
Expand All @@ -115,8 +103,9 @@ class DispatcherTests: XCTestCase {
func testCurrentDispatcherDispatchQueue() {
let dispatchQueue = DispatchQueue(label: "")
dispatchQueue.async {
self.dispatcher = CurrentDispatcher()
let dispatchWorkItem = self.dispatcher.execute(qos: nil, flags: nil, block: { sleep(2) })
self.dispatcher = .current
let dispatchWorkItem = DispatchWorkItem(qos: .default, flags: .assignCurrentContext) { sleep(2) }
self.dispatcher.execute(dispatchWorkItem)
XCTAssertFalse(dispatchWorkItem.isCancelled)
dispatchWorkItem.cancel()
XCTAssertTrue(dispatchWorkItem.isCancelled)
Expand Down
64 changes: 64 additions & 0 deletions KommanderTests/KommanderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,57 @@ class KommanderTests: XCTestCase {
waitForExpectations(timeout: 100, handler: nil)
}

func test_nCalls_withDelay() {

let ex = expectation(description: String(describing: type(of: self)))

var successes = 0
let calls = Int(arc4random_uniform(10) + 1)

for i in 0..<calls {
interactor.getCounter(name: "C\(i)", to: 3)
.onSuccess({ (name) in
successes+=1
if successes>=calls {
ex.fulfill()
}
})
.onError({ (error) in
ex.fulfill()
XCTFail()
})
.execute(after: .seconds(1))
}

waitForExpectations(timeout: 100, handler: nil)
}

func test_nCalls_andCancel() {

let ex = expectation(description: String(describing: type(of: self)))

var errors = 0
let calls = Int(arc4random_uniform(10) + 1)

for i in 0..<calls {
interactor.getCounter(name: "C\(i)", to: 3)
.onSuccess({ (name) in
ex.fulfill()
XCTFail()
})
.onError({ (error) in
errors+=1
if errors>=calls {
ex.fulfill()
}
})
.execute()
.cancel(true, after: .seconds(2))
}

waitForExpectations(timeout: 100, handler: nil)
}

func test_nCalls() {

let ex = expectation(description: String(describing: type(of: self)))
Expand Down Expand Up @@ -211,6 +262,19 @@ class KommanderTests: XCTestCase {
waitForExpectations(timeout: 100, handler: nil)
}

func testInitializers() {
let custom = Kommander(name: "Test", maxConcurrentOperationCount: 2)
XCTAssertEqual(custom.executor.operationQueue.name, "Test")
XCTAssertEqual(custom.executor.operationQueue.maxConcurrentOperationCount, 2)
XCTAssertEqual(Kommander.main.executor.operationQueue, OperationQueue.main)
XCTAssertEqual(Kommander.current.executor.operationQueue, OperationQueue.current)
XCTAssertEqual(Kommander.default.executor.operationQueue.qualityOfService, .default)
XCTAssertEqual(Kommander.userInteractive.executor.operationQueue.qualityOfService, .userInteractive)
XCTAssertEqual(Kommander.userInitiated.executor.operationQueue.qualityOfService, .userInitiated)
XCTAssertEqual(Kommander.utility.executor.operationQueue.qualityOfService, .utility)
XCTAssertEqual(Kommander.background.executor.operationQueue.qualityOfService, .background)
}

}

extension KommanderTests {
Expand Down
60 changes: 59 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,22 @@ dependencies: [

## Usage

#### Making, executing and cancelling Kommands:

```swift
Kommander().makeKommand {
// Your code here
}.execute()
```

```swift
Kommander().makeKommand { () -> String in
Kommander().makeKommand {
// Your code here
}.execute(after: .seconds(2))
```

```swift
Kommander().makeKommand {
return "Your string"
}.onSuccess { yourString in
print(yourString)
Expand All @@ -113,6 +121,56 @@ let kommand = Kommander().makeKommand { () -> Any? in
kommand.cancel()
```

#### Creating Kommanders:

```swift
Kommander(deliverer: Dispatcher = .current, executor: Dispatcher = .default)

Kommander(deliverer: Dispatcher = .current, name: String, qos: QualityOfService = .default, maxConcurrentOperationCount: Int = .default)
```

```swift
Kommander.main

Kommander.current

Kommander.default

Kommander.userInteractive

Kommander.userInitiated

Kommander.utility

Kommander.background
```

#### Creating Dispatchers:

```swift
CurrentDispatcher()

MainDispatcher()

Dispatcher(name: String, qos: QualityOfService = .default, maxConcurrentOperationCount: Int = .default)
```

```swift
Dispatcher.main

Dispatcher.current

Dispatcher.default

Dispatcher.userInteractive

Dispatcher.userInitiated

Dispatcher.utility

Dispatcher.background
```

## Etc.

* Contributions are very welcome.
Expand Down
55 changes: 19 additions & 36 deletions Source/Dispatcher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,20 @@ open class Dispatcher {
/// Dispatcher with default quality of service
open static var `default`: Dispatcher { return Dispatcher() }
/// Dispatcher with user interactive quality of service
open static var userInteractive: Dispatcher { return Dispatcher(name: nil, qos: .userInteractive) }
open static var userInteractive: Dispatcher { return Dispatcher(qos: .userInteractive) }
/// Dispatcher with user initiated quality of service
open static var userInitiated: Dispatcher { return Dispatcher(name: nil, qos: .userInitiated) }
open static var userInitiated: Dispatcher { return Dispatcher(qos: .userInitiated) }
/// Dispatcher with utility quality of service
open static var utility: Dispatcher { return Dispatcher(name: nil, qos: .utility) }
open static var utility: Dispatcher { return Dispatcher(qos: .utility) }
/// Dispatcher with background quality of service
open static var background: Dispatcher { return Dispatcher(name: nil, qos: .background) }

/// Dispatcher instance with default OperationQueue
public convenience init() {
self.init(name: nil, qos: .default)
}
open static var background: Dispatcher { return Dispatcher(qos: .background) }

/// Dispatcher instance with custom OperationQueue
public init(name: String?, qos: QualityOfService?, maxConcurrentOperationCount: Int? = nil) {
operationQueue.name = name ?? UUID().uuidString
operationQueue.qualityOfService = qos ?? .default
operationQueue.maxConcurrentOperationCount = maxConcurrentOperationCount ?? OperationQueue.defaultMaxConcurrentOperationCount
}

/// Dispatcher instance with custom DispatchQueue
@available(*, deprecated, message: "This will be removed in Kommander 0.9. Use `Dispatcher.init(name:qos:maxConcurrentOperationCount:)` instead.")
public init(label: String?, qos: DispatchQoS?, attributes: DispatchQueue.Attributes? = nil, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency? = nil, target: DispatchQueue? = nil) {
dispatchQueue = DispatchQueue(label: label ?? UUID().uuidString, qos: qos ?? .default, attributes: attributes ?? .concurrent, autoreleaseFrequency: autoreleaseFrequency ?? .inherit, target: target)
public init(name: String = UUID().uuidString, qos: QualityOfService = .default, maxConcurrentOperationCount: Int = OperationQueue.defaultMaxConcurrentOperationCount) {
operationQueue.name = name
operationQueue.qualityOfService = qos
operationQueue.maxConcurrentOperationCount = maxConcurrentOperationCount
dispatchQueue = DispatchQueue(label: name, qos: dispatchQoS(qos), attributes: .concurrent, autoreleaseFrequency: .inherit, target: operationQueue.underlyingQueue)
}

/// Execute Operation instance in OperationQueue
Expand Down Expand Up @@ -89,15 +79,6 @@ open class Dispatcher {
dispatchQueue.asyncAfter(deadline: .now() + delay, execute: block)
}

/// Execute block in DispatchQueue using custom DispatchWorkItem instance after delay
@available(*, deprecated, message: "This will be removed in Kommander 0.9. Use `execute(delay:work:)` instead.")
open func execute(after delay: DispatchTimeInterval, qos: DispatchQoS?, flags: DispatchWorkItemFlags?, block: @escaping @convention(block) () -> ()) {
guard delay != .never else {
return
}
dispatchQueue.asyncAfter(deadline: .now() + delay, qos: qos ?? .default, flags: flags ?? .assignCurrentContext, execute: block)
}

/// Execute DispatchWorkItem instance in DispatchQueue after delay
open func execute(after delay: DispatchTimeInterval, work: DispatchWorkItem) {
guard delay != .never else {
Expand All @@ -107,17 +88,19 @@ open class Dispatcher {
dispatchQueue.asyncAfter(deadline: .now() + delay, execute: work)
}

/// Execute block in DispatchQueue using custom DispatchWorkItem instance
@available(*, deprecated, message: "This will be removed in Kommander 0.9. Use `execute(work:)` instead.")
@discardableResult open func execute(qos: DispatchQoS?, flags: DispatchWorkItemFlags?, block: @escaping @convention(block) () -> ()) -> DispatchWorkItem {
let work = DispatchWorkItem(qos: qos ?? .default, flags: flags ?? .assignCurrentContext, block: block)
execute(work)
return work
}

/// Execute DispatchWorkItem instance in DispatchQueue
open func execute(_ work: DispatchWorkItem) {
dispatchQueue.async(execute: work)
}

private final func dispatchQoS(_ qos: QualityOfService) -> DispatchQoS {
switch qos {
case .userInteractive: return .userInteractive
case .userInitiated: return .userInitiated
case .utility: return .utility
case .background: return .background
default: return .default
}
}

}
2 changes: 1 addition & 1 deletion Source/Kommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ open class Kommand<Result> {
final weak var work: DispatchWorkItem?

/// Kommand<Result> instance with your deliverer, your executor and your actionBlock returning generic and throwing errors
public init(deliverer: Dispatcher, executor: Dispatcher, actionBlock: @escaping ActionBlock) {
public init(deliverer: Dispatcher = .current, executor: Dispatcher = .default, actionBlock: @escaping ActionBlock) {
self.deliverer = deliverer
self.executor = executor
self.actionBlock = actionBlock
Expand Down
Loading

0 comments on commit 3d573eb

Please sign in to comment.