diff --git a/Hydra.xcodeproj/project.pbxproj b/Hydra.xcodeproj/project.pbxproj index 88f8053..e153964 100644 --- a/Hydra.xcodeproj/project.pbxproj +++ b/Hydra.xcodeproj/project.pbxproj @@ -560,7 +560,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0830; - LastUpgradeCheck = 1020; + LastUpgradeCheck = 1250; ORGANIZATIONNAME = Hydra; TargetAttributes = { 37ACAE351F0FB53A00ED284A = { @@ -897,7 +897,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; DEVELOPMENT_TEAM = E5DU3FA699; INFOPLIST_FILE = DemoApp/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.3; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.danielemargutti.DemoApp; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -914,7 +914,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; DEVELOPMENT_TEAM = E5DU3FA699; INFOPLIST_FILE = DemoApp/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.3; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.danielemargutti.DemoApp; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -945,6 +945,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -970,7 +971,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -1005,6 +1006,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -1024,7 +1026,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_VERSION = 5.0; @@ -1047,7 +1049,7 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = Configs/Hydra.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; ONLY_ACTIVE_ARCH = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.Hydra.Hydra-iOS"; @@ -1069,7 +1071,7 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = Configs/Hydra.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.Hydra.Hydra-iOS"; PRODUCT_NAME = Hydra; @@ -1169,7 +1171,7 @@ SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; TARGETED_DEVICE_FAMILY = 3; - TVOS_DEPLOYMENT_TARGET = 9.0; + TVOS_DEPLOYMENT_TARGET = 12.0; }; name = Debug; }; @@ -1192,7 +1194,7 @@ SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; TARGETED_DEVICE_FAMILY = 3; - TVOS_DEPLOYMENT_TARGET = 9.0; + TVOS_DEPLOYMENT_TARGET = 12.0; }; name = Release; }; @@ -1284,7 +1286,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.Hydra.Hydra-tvOS-Tests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; - TVOS_DEPLOYMENT_TARGET = 9.1; + TVOS_DEPLOYMENT_TARGET = 12.0; }; name = Debug; }; @@ -1298,7 +1300,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - TVOS_DEPLOYMENT_TARGET = 9.1; + TVOS_DEPLOYMENT_TARGET = 12.0; }; name = Release; }; diff --git a/Hydra.xcodeproj/xcshareddata/xcschemes/Hydra-iOS.xcscheme b/Hydra.xcodeproj/xcshareddata/xcschemes/Hydra-iOS.xcscheme index a6252ac..7cdf482 100644 --- a/Hydra.xcodeproj/xcshareddata/xcschemes/Hydra-iOS.xcscheme +++ b/Hydra.xcodeproj/xcshareddata/xcschemes/Hydra-iOS.xcscheme @@ -1,6 +1,6 @@ + shouldUseLaunchSchemeArgsEnv = "YES" + codeCoverageEnabled = "YES"> + + + + @@ -40,17 +49,6 @@ - - - - - - - - + shouldUseLaunchSchemeArgsEnv = "YES" + codeCoverageEnabled = "YES"> + + + + @@ -40,17 +49,6 @@ - - - - - - - - + shouldUseLaunchSchemeArgsEnv = "YES" + codeCoverageEnabled = "YES"> + + + + @@ -40,17 +49,6 @@ - - - - - - - - + shouldUseLaunchSchemeArgsEnv = "YES" + codeCoverageEnabled = "YES"> - - - - 'MIT', :file => 'LICENSE' } diff --git a/README.md b/README.md index a9438bf..591c1bf 100644 --- a/README.md +++ b/README.md @@ -223,6 +223,9 @@ class SomeTableViewCell: UITableViewCell { Have you ever dream to write asynchronous code like its synchronous counterpart? Hydra was heavily inspired by [Async/Await specification in ES8 (ECMAScript 2017) ](https://github.com/tc39/ecmascript-asyncawait) which provides a powerful way to write async doe in a sequential manner. Using `async` and `await` is pretty simple. + +> NOTE: Since Hydra 2.0.6 the await function is available under Hydra.await() function in order to supress the Xcode 12.5+ warning (await will become a Swift standard function soon!) + For example the code above can be rewritten directly as: ```swift @@ -230,11 +233,11 @@ For example the code above can be rewritten directly as: // context (if omitted `background` thread is used) and return an Int value. let asyncFunc = async({ _ -> Int in // you must specify the return of the Promise, here an Int // With `await` the async code is resolved in a sync manner - let loggedUser = try await(loginUser(username,pass)) + let loggedUser = try Hydra.await(loginUser(username,pass)) // one promise... - let followersList = try await(getFollowers(loggedUser)) + let followersList = try Hydra.await(getFollowers(loggedUser)) // after another... - let countUnfollowed = try await(unfollow(followersList)) + let countUnfollowed = try Hydra.await(unfollow(followersList)) // ... linearly // Then our async promise will be resolved with the end value return countUnfollowed @@ -257,7 +260,7 @@ Below an example of the async function which will be executed without delay in b ```swift async({ print("And now some intensive task...") - let result = try! await(.background, { resolve,reject, _ in + let result = try! Hydra.await(.background, { resolve,reject, _ in delay(10, context: .background, closure: { // jut a trick for our example resolve(5) }) @@ -322,7 +325,7 @@ invalidator.invalidate() Await can be also used in conjuction with zip to resolve all promises from a list: ```swift -let (resultA,resultB) = await(zip(promiseA,promiseB)) +let (resultA,resultB) = Hydra.await(zip(promiseA,promiseB)) print(resultA) print(resultB) ``` diff --git a/Sources/Hydra/Promise+Await.swift b/Sources/Hydra/Promise+Await.swift index 6801389..9fd19dd 100644 --- a/Sources/Hydra/Promise+Await.swift +++ b/Sources/Hydra/Promise+Await.swift @@ -66,8 +66,9 @@ public prefix func ..! (_ promise: Promise) -> T? { /// - Returns: fulfilled value of the promise /// - Throws: throws an exception if promise fails due to an error @discardableResult +@available(*, deprecated, renamed: "Hydra.await") public func await(in context: Context? = nil, _ promise: Promise) throws -> T { - return try (context ?? awaitContext).await(promise) + return try Hydra.await(in: context, promise) } /// Awaits that the given body is resolved. This is a shortcut which simply create a Promise; as for a Promise you need to @@ -79,9 +80,39 @@ public func await(in context: Context? = nil, _ promise: Promise) throws - /// - Returns: the value of the promise /// - Throws: an exception if operation fails @discardableResult +@available(*, deprecated, renamed: "Hydra.await") public func await(in context: Context = .background, _ body: @escaping ((_ fulfill: @escaping (T) -> (), _ reject: @escaping (Error) -> (), _ operation: PromiseStatus) throws -> ())) throws -> T { - let promise = Promise(in: context, body) - return try await(in: context, promise) + return try Hydra.await(in: context, body) +} + +public enum Hydra { + + /// Awaits that the given promise fulfilled with its value or throws an error if the promise fails + /// + /// - Parameters: + /// - context: context in which you want to execute the operation. If not specified default concurrent `awaitContext` is used instead. + /// - promise: target promise + /// - Returns: fulfilled value of the promise + /// - Throws: throws an exception if promise fails due to an error + @discardableResult + public static func await(in context: Context? = nil, _ promise: Promise) throws -> T { + return try (context ?? awaitContext).await(promise) + } + + /// Awaits that the given body is resolved. This is a shortcut which simply create a Promise; as for a Promise you need to + /// call `resolve` or `reject` in order to complete it. + /// + /// - Parameters: + /// - context: context in which the body is executed (if not specified `background` is used) + /// - body: closure to execute + /// - Returns: the value of the promise + /// - Throws: an exception if operation fails + @discardableResult + public static func await(in context: Context = .background, _ body: @escaping ((_ fulfill: @escaping (T) -> (), _ reject: @escaping (Error) -> (), _ operation: PromiseStatus) throws -> ())) throws -> T { + let promise = Promise(in: context, body) + return try Hydra.await(in: context, promise) + } + } diff --git a/Tests/HydraTests/HydraTests.swift b/Tests/HydraTests/HydraTests.swift index d92f6aa..0de5930 100644 --- a/Tests/HydraTests/HydraTests.swift +++ b/Tests/HydraTests/HydraTests.swift @@ -578,7 +578,7 @@ class HydraTestThen: XCTestCase { do { let startValue = 5 // let result1 = try ..self.intPromise(startValue) - let result1 = try await(self.intPromise(startValue)) + let result1 = try Hydra.await(self.intPromise(startValue)) let result2 = try ..self.intPromiseDelay(result1 * 2, delay: 0.5) let result3 = try ..self.intPromiseDelay(result2 * 2, delay: 0.5) if result3 == startValue * 4 {