├── .DS_Store
├── Await.podspec
├── LICENSE
├── Package.swift
├── README.md
├── Sources
├── .DS_Store
└── Await
│ ├── .DS_Store
│ ├── AwaitCompletable.swift
│ ├── AwaitError.swift
│ ├── AwaitTask.swift
│ └── DispatchQueue+Await.swift
└── Tests
├── AwaitTests
├── AwaitTests.swift
└── XCTestManifests.swift
└── LinuxMain.swift
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiny2n/Await/129b17dadec5bbe607db2266b1d9ea419a4c3077/.DS_Store
--------------------------------------------------------------------------------
/Await.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "Await"
3 | s.version = "1.2.0"
4 | s.homepage = 'https://github.com/tiny2n/Await.git'
5 | s.summary = "Asynchronous Programming with async and await base protocol oriented programming"
6 | s.license = { :type => "MIT", :file => "LICENSE" }
7 | s.author = { "tiny2n" => "tiy2n@naver.com" }
8 | s.source = { :git => "https://github.com/tiny2n/Await.git", :tag => s.version }
9 | s.ios.deployment_target = '9.0'
10 | s.source_files = "Sources/Await/*.swift"
11 | end
12 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 Choi Joongkwan. All rights reserved.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FR
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.3
2 | // The swift-tools-version declares the minimum version of Swift required to build this package.
3 |
4 | import PackageDescription
5 |
6 | let package = Package(
7 | name: "Await",
8 | products: [
9 | // Products define the executables and libraries a package produces, and make them visible to other packages.
10 | .library(
11 | name: "Await",
12 | targets: ["Await"]),
13 | ],
14 | dependencies: [
15 | // Dependencies declare other packages that this package depends on.
16 | // .package(url: /* package url */, from: "1.0.0"),
17 | ],
18 | targets: [
19 | // Targets are the basic building blocks of a package. A target can define a module or a test suite.
20 | // Targets can depend on other targets in this package, and on products in packages this package depends on.
21 | .target(
22 | name: "Await",
23 | dependencies: []),
24 | .testTarget(
25 | name: "AwaitTests",
26 | dependencies: ["Await"]),
27 | ]
28 | )
29 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | [](https://developer.apple.com/swift)
4 | [](https://developer.apple.com/ios)
5 |
6 |
Await
7 |
8 | Overview
9 | -------------
10 | Asynchronous Programming with async and await base protocol oriented programming
11 | _Await_ is a powerful Swift library
12 |
13 | C# async and await
14 | https://msdn.microsoft.com/en-us//library/hh191443(v=vs.110).aspx
15 |
16 | ### Introducation
17 |
18 | __Requires Swift 3 or later
19 |
20 | ### Installation
21 |
22 | Add the files to your project manually by dragging the Await directory into your Xcode project.
23 |
24 | or
25 |
26 | [CocoaPods](https://cocoapods.org):
27 |
28 | ```ruby
29 | pod 'Await', :git => 'https://github.com/tiny2n/Await.git'
30 | ```
31 |
32 | ### Usage
33 |
34 | write this:
35 | ```swift
36 | // async and await
37 | async {
38 | let result = try await(AwaitExecute()) // AwaitCompletable Type
39 | ...
40 | }
41 |
42 | ```
43 |
44 | AwaitCompletable protocol this:
45 | ```swift
46 | // AwaitCompletable
47 | public protocol AwaitCompletable {
48 | associatedtype AwaitCompletableType
49 |
50 | var queue: DispatchQueue { get }
51 | var timeout: DispatchTimeInterval? { get }
52 |
53 | func execute(_ completion: @escaping (AwaitCompletableResult) -> Void)
54 | }
55 |
56 | ```
57 |
58 | Custom this:
59 | ```swift
60 | // Custom Await Completable
61 | public struct AsyncObjectTask: AwaitCompletable {
62 | func execute(_ completion: @escaping (AwaitCompletableResult) -> Void) {
63 | // execute task
64 |
65 | <#async code#>
66 |
67 | completion(.success(<#await completable type#>))
68 | // or completion(.failure(<#error#>))
69 | }
70 | }
71 |
72 | ```
73 |
74 | example this:
75 | ```swift
76 |
77 | // async block is Asynchronous
78 | // await block is Synchronous
79 |
80 | // serial call
81 | async {
82 | do {
83 | let odd = try await(ACSum0To1000000000Odd())
84 | let even = try await(ACSum0To1000000000Even())
85 | let sum = try await(ACResultSum(odd, even))
86 |
87 | print(">>> odd: \(odd)")
88 | print(">>> even: \(even)")
89 | print(">>> sum: \(sum)")
90 | }
91 | catch AwaitError.nil {
92 | print("throw nil")
93 | }
94 | catch AwaitError.timeout {
95 | print("throw timeout")
96 | }
97 | catch {
98 | print("thorw unknown")
99 | }
100 | }
101 |
102 | ```
103 |
104 | ```swift
105 | // using subclassing by class AwaitConcurrentSupport
106 | // concurrent call
107 | async {
108 | do {
109 | let result = try await(ACSum0To1000000000Even(), ACSum0To1000000000Odd())
110 | print(">>> count: \(result.count)")
111 | print(">>> even: \(result[1])")
112 | print(">>> odd: \(result[0])")
113 | }
114 | catch {
115 | // Type: AwaitConcurrentError.concurrent
116 | print("[Error] \(error)")
117 | }
118 | }
119 |
120 | ```
121 |
122 |
123 | ### License
124 |
125 | **Await** is available under the MIT license. See the [LICENSE](LICENSE) file for more info.
126 |
--------------------------------------------------------------------------------
/Sources/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiny2n/Await/129b17dadec5bbe607db2266b1d9ea419a4c3077/Sources/.DS_Store
--------------------------------------------------------------------------------
/Sources/Await/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tiny2n/Await/129b17dadec5bbe607db2266b1d9ea419a4c3077/Sources/Await/.DS_Store
--------------------------------------------------------------------------------
/Sources/Await/AwaitCompletable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AwaitCompletable.swift
3 | // Await
4 | //
5 | // Created by joongkwan.choi on 2017. 8. 28..
6 | // Copyright © 2017 tiny2n. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public enum AwaitCompletableResult {
12 | case success(T)
13 | case failure(Error)
14 | }
15 |
16 | public protocol AwaitCompletable {
17 | associatedtype AwaitCompletableType
18 |
19 | var queue: DispatchQueue { get }
20 | var timeout: DispatchTimeInterval? { get set }
21 |
22 | func execute(_ completion: @escaping (AwaitCompletableResult) -> Void)
23 | }
24 |
25 | extension AwaitCompletable {
26 |
27 | public var queue: DispatchQueue {
28 | return DispatchQueue(label: "com.tiny2n.await.queue.completable", attributes: .concurrent)
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/Sources/Await/AwaitError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AwaitError.swift
3 | // Await
4 | //
5 | // Created by joongkwan.choi on 2017. 8. 28..
6 | // Copyright © 2017 tiny2n. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public enum AwaitError: Error {
12 | case failure(Error)
13 | case timeout
14 | }
15 |
--------------------------------------------------------------------------------
/Sources/Await/AwaitTask.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AwaitTask.swift
3 | // Await-Demo
4 | //
5 | // Created by joongkwan.choi on 15/10/2019.
6 | // Copyright © 2019 tiny2n. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | final public class AwaitTask {
12 | private var value: Value
13 |
14 | public init(value: Value) {
15 | self.value = value
16 | }
17 |
18 | public func await() -> Value {
19 | return value
20 | }
21 | }
22 |
23 | @discardableResult
24 | public func await(_ task: AwaitTask) throws -> Value {
25 | return task.await()
26 | }
27 |
--------------------------------------------------------------------------------
/Sources/Await/DispatchQueue+Await.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DispatchQueue+Await.swift
3 | // Await
4 | //
5 | // Created by joongkwan.choi on 2017. 8. 28..
6 | // Copyright © 2017 tiny2n. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public let async = DispatchQueue(label: "com.tiny2n.await.queue.async", attributes: .concurrent)
12 | public let await = DispatchQueue(label: "com.tiny2n.await.queue.await", attributes: .concurrent)
13 |
14 | extension DispatchQueue {
15 |
16 | final public func await(_ completable: T) throws -> T.AwaitCompletableType {
17 | var result: Result = .failure(AwaitError.timeout)
18 | let semaphore = DispatchSemaphore(value: 0)
19 |
20 | completable.queue.async {
21 | completable.execute({ (execute) in
22 | switch execute {
23 | case let .success(response):
24 | result = .success(response)
25 | case let .failure(error):
26 | result = .failure(error)
27 | }
28 |
29 | semaphore.signal()
30 | })
31 | }
32 |
33 | // waiting for semaphore signal
34 | let timeout = waitingforTimeout(completable.timeout)
35 | _ = semaphore.wait(timeout: timeout)
36 |
37 | // return result or throws error
38 | switch result {
39 | case .success(let value):
40 | return value
41 | case .failure(let error):
42 | throw error
43 | }
44 | }
45 |
46 | private func waitingforTimeout(_ timeout: DispatchTimeInterval?) -> DispatchTime {
47 | var result: DispatchTime = .distantFuture
48 | if let timeout = timeout {
49 | result = .now() + timeout
50 | }
51 |
52 | return result
53 | }
54 | }
55 |
56 | public func await(_ completable: T) throws -> T.AwaitCompletableType {
57 | return try await.await(completable)
58 | }
59 |
60 | public func async(_ block: @escaping () -> Void) {
61 | async.async { block() }
62 | }
63 |
--------------------------------------------------------------------------------
/Tests/AwaitTests/AwaitTests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 | @testable import Await
3 |
4 | final class AwaitTests: XCTestCase {
5 | func testExample() {
6 | // This is an example of a functional test case.
7 | // Use XCTAssert and related functions to verify your tests produce the correct
8 | // results.
9 | }
10 |
11 | static var allTests = [
12 | ("testExample", testExample),
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/Tests/AwaitTests/XCTestManifests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 |
3 | #if !canImport(ObjectiveC)
4 | public func allTests() -> [XCTestCaseEntry] {
5 | return [
6 | testCase(AwaitTests.allTests),
7 | ]
8 | }
9 | #endif
10 |
--------------------------------------------------------------------------------
/Tests/LinuxMain.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 |
3 | import AwaitTests
4 |
5 | var tests = [XCTestCaseEntry]()
6 | tests += AwaitTests.allTests()
7 | XCTMain(tests)
8 |
--------------------------------------------------------------------------------