Skip to content
This repository has been archived by the owner on Jul 5, 2024. It is now read-only.

Commit

Permalink
Async/BlockConsumerOperation
Browse files Browse the repository at this point in the history
  • Loading branch information
mattmassicotte committed Mar 24, 2020
1 parent 740f880 commit bb81e4f
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 3 deletions.
8 changes: 8 additions & 0 deletions OperationPlus.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
C9B0219D2203D6AA006A1D9F /* OperationQueue+Dependencies.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9B021962203D6AA006A1D9F /* OperationQueue+Dependencies.swift */; };
C9B0219F2203D6AA006A1D9F /* Operation+Dependencies.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9B021972203D6AA006A1D9F /* Operation+Dependencies.swift */; };
C9B021A12203D6AA006A1D9F /* OperationQueue+Creation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9B021982203D6AA006A1D9F /* OperationQueue+Creation.swift */; };
C9C30EA72428DC01003BE31A /* BlockConsumerOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9C30EA62428DC01003BE31A /* BlockConsumerOperation.swift */; };
C9C30EA92428DC1D003BE31A /* AsyncBlockConsumerOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9C30EA82428DC1D003BE31A /* AsyncBlockConsumerOperation.swift */; };
C9CC1D442206735800F7DCAE /* OperationQueue+Enqueuing.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9CC1D432206735800F7DCAE /* OperationQueue+Enqueuing.swift */; };
C9CC1D4622075FE900F7DCAE /* BaseOperationError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9CC1D4522075FE900F7DCAE /* BaseOperationError.swift */; };
C9CC1D482207CA5600F7DCAE /* AsyncBlockOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9CC1D472207CA5600F7DCAE /* AsyncBlockOperationTests.swift */; };
Expand Down Expand Up @@ -101,6 +103,8 @@
C9B021982203D6AA006A1D9F /* OperationQueue+Creation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "OperationQueue+Creation.swift"; sourceTree = "<group>"; };
C9B021B92203DE8E006A1D9F /* OperationPlusTests.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = OperationPlusTests.xcconfig; sourceTree = "<group>"; };
C9B022A62205287F006A1D9F /* xcconfigs */ = {isa = PBXFileReference; lastKnownFileType = folder; path = xcconfigs; sourceTree = SOURCE_ROOT; };
C9C30EA62428DC01003BE31A /* BlockConsumerOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockConsumerOperation.swift; sourceTree = "<group>"; };
C9C30EA82428DC1D003BE31A /* AsyncBlockConsumerOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncBlockConsumerOperation.swift; sourceTree = "<group>"; };
C9CC1D432206735800F7DCAE /* OperationQueue+Enqueuing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OperationQueue+Enqueuing.swift"; sourceTree = "<group>"; };
C9CC1D4522075FE900F7DCAE /* BaseOperationError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseOperationError.swift; sourceTree = "<group>"; };
C9CC1D472207CA5600F7DCAE /* AsyncBlockOperationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncBlockOperationTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -175,6 +179,8 @@
C949420A232C043D00BCFC88 /* AsyncConsumerProducerOperation.swift */,
C9494212232DBEE900BCFC88 /* BlockConsumerProducerOperation.swift */,
C9494210232DB95000BCFC88 /* AsyncBlockConsumerProducerOperation.swift */,
C9C30EA62428DC01003BE31A /* BlockConsumerOperation.swift */,
C9C30EA82428DC1D003BE31A /* AsyncBlockConsumerOperation.swift */,
C9B021762203D1C2006A1D9F /* OperationPlus.xcconfig */,
C9B021932203D677006A1D9F /* Extensions */,
);
Expand Down Expand Up @@ -371,6 +377,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C9C30EA92428DC1D003BE31A /* AsyncBlockConsumerOperation.swift in Sources */,
C9B021A12203D6AA006A1D9F /* OperationQueue+Creation.swift in Sources */,
C9CC1D4622075FE900F7DCAE /* BaseOperationError.swift in Sources */,
C9B021992203D6AA006A1D9F /* OperationQueue+Emptied.swift in Sources */,
Expand All @@ -384,6 +391,7 @@
C9B0219D2203D6AA006A1D9F /* OperationQueue+Dependencies.swift in Sources */,
C9B021502203D064006A1D9F /* ProducerOperation.swift in Sources */,
C9B0214C2203CFD1006A1D9F /* BaseOperation.swift in Sources */,
C9C30EA72428DC01003BE31A /* BlockConsumerOperation.swift in Sources */,
C9B021522203D086006A1D9F /* AsyncProducerOperation.swift in Sources */,
C9494211232DB95000BCFC88 /* AsyncBlockConsumerProducerOperation.swift in Sources */,
C9B0219F2203D6AA006A1D9F /* Operation+Dependencies.swift in Sources */,
Expand Down
28 changes: 28 additions & 0 deletions OperationPlus/AsyncBlockConsumerOperation.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// AsyncBlockConsumerOperation.swift
// OperationPlus
//
// Created by Matt Massicotte on 2020-03-23.
// Copyright © 2020 Chime Systems Inc. All rights reserved.
//

import Foundation

/// An asynchronous variant of BlockConsumerOperation
public class AsyncBlockConsumerOperation<Input>: AsyncConsumerOperation<Input> {
public typealias CompletionHandler = (Input, @escaping () -> Void) -> Void

private let block: CompletionHandler

public init(producerOp: ProducerOperation<Input>, block: @escaping CompletionHandler) {
self.block = block

super.init(producerOp: producerOp)
}

override open func main(with producedValue: Input) {
block(producedValue, {
self.finish()
})
}
}
26 changes: 26 additions & 0 deletions OperationPlus/BlockConsumerOperation.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// BlockConsumerOperation.swift
// OperationPlus
//
// Created by Matt Massicotte on 2020-03-23.
// Copyright © 2020 Chime Systems Inc. All rights reserved.
//

import Foundation

/// A block-based version of ConsumerOperation
public class BlockConsumerOperation<Input>: ConsumerOperation<Input> {
private let block: (Input) -> Void

public init(producerOp: ProducerOperation<Input>, block: @escaping (Input) -> Void) {
self.block = block

super.init(producerOp: producerOp)
}

override open func main(with producedValue: Input) {
block(producedValue)

self.finish()
}
}
2 changes: 1 addition & 1 deletion OperationPlus/BlockConsumerProducerOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import Foundation

/// An block-based version of ConsumerProducerOperation
/// A block-based version of ConsumerProducerOperation
public class BlockConsumerProducerOperation<Input, Output>: ConsumerProducerOperation<Input, Output> {
public typealias Block = (Input) -> Output?

Expand Down
4 changes: 2 additions & 2 deletions OperationPlus/OperationPlus.xcconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
PRODUCT_NAME = OperationPlus
PRODUCT_BUNDLE_IDENTIFIER = com.chimehq.OperationPlus
PRODUCT_MODULE_NAME = OperationPlus
CURRENT_PROJECT_VERSION = 9
MARKETING_VERSION = 1.5.1
CURRENT_PROJECT_VERSION = 10
MARKETING_VERSION = 1.5.2

INFOPLIST_FILE = OperationPlus/Info.plist

Expand Down
41 changes: 41 additions & 0 deletions OperationPlusTests/ProducerConsumerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -169,4 +169,45 @@ class ProducerConsumerTests: XCTestCase {
XCTAssertTrue(op.isCancelled)
XCTAssertEqual(op.value, 10)
}

func testAsyncBlockConsumerOperation() {
let opA = IntProducerOperation(intValue: 10)

let valueExpectation = expectation(description: "Got Value")

let blockOp = AsyncBlockConsumerOperation<Int>(producerOp: opA) { (value, opCompletionBlock) in
DispatchQueue.global().async {
if value == 10 {
valueExpectation.fulfill()
}
opCompletionBlock()
}
}

let opExpectation = OperationExpectation(operations: [opA, blockOp])

wait(for: [valueExpectation, opExpectation], timeout: 1.0)

XCTAssertTrue(opA.isFinished)
XCTAssertTrue(blockOp.isFinished)
}

func testBlockConsumerOperation() {
let opA = IntProducerOperation(intValue: 10)

let valueExpectation = expectation(description: "Got Value")

let blockOp = BlockConsumerOperation<Int>(producerOp: opA) { (value) in
if value == 10 {
valueExpectation.fulfill()
}
}

let opExpectation = OperationExpectation(operations: [opA, blockOp])

wait(for: [valueExpectation, opExpectation], timeout: 1.0)

XCTAssertTrue(opA.isFinished)
XCTAssertTrue(blockOp.isFinished)
}
}

0 comments on commit bb81e4f

Please sign in to comment.