├── .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 | [![Language](http://img.shields.io/badge/language-swift-brightgreen.svg?style=flat)](https://developer.apple.com/swift) 4 | [![Platform](https://img.shields.io/cocoapods/p/DeepLinkSDK.svg?style=flat)](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 | --------------------------------------------------------------------------------