From 59847871ba05f22a09652f2eff664d1cc3cac8d3 Mon Sep 17 00:00:00 2001 From: Max Howell Date: Wed, 14 Feb 2018 14:07:17 -0500 Subject: [PATCH] Xcode 9.3 / Swift 4.1 / Swift 3.3 updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Strictly I’d feel better to test all configurations, but PromiseKit only uses Foundation, so the chance that for some reason there is an API break or worse some kind of runtime issue is pretty low and I feel that we have to be kinder to Travis’s free infrastructure. Tag 6.0.2 --- .travis.yml | 60 ++++++++++--------- Documentation/CommonPatterns.md | 8 +-- Documentation/Installation.md | 22 ++++--- PromiseKit.xcodeproj/project.pbxproj | 16 +++-- .../xcschemes/PromiseKit.xcscheme | 4 +- README.md | 4 +- Sources/Thenable.swift | 13 +--- Sources/when.swift | 4 ++ Tests/A+/0.0.0.swift | 2 +- 9 files changed, 70 insertions(+), 63 deletions(-) diff --git a/.travis.yml b/.travis.yml index be3868af0..3f8c94a5a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,36 +1,38 @@ matrix: include: - - {osx_image: xcode8.3, env: 'PLAT=macOS SWFT=3.1 DST="arch=x86_64"', os: osx, language: objective-c} - - {osx_image: xcode8.3, env: 'PLAT=iOS SWFT=3.1 DST="OS=8.4,name=iPhone 4s"', os: osx, language: objective-c} - - {osx_image: xcode8.3, env: 'PLAT=iOS SWFT=3.1 DST="OS=9.3,name=iPhone SE"', os: osx, language: objective-c} - - {osx_image: xcode8.3, env: 'PLAT=iOS SWFT=3.1 DST="OS=10.3.1,name=iPhone SE"', os: osx, language: objective-c} - - {osx_image: xcode8.3, env: 'PLAT=tvOS SWFT=3.1 DST="OS=10.2,name=Apple TV 1080p"', os: osx, language: objective-c} - - {osx_image: xcode8.3, env: 'PLAT=watchOS SWFT=3.1 DST="OS=2.2,name=Apple Watch - 38mm"', os: osx, language: objective-c} - - {osx_image: xcode8.3, env: 'PLAT=watchOS SWFT=3.1 DST="OS=3.2,name=Apple Watch - 38mm"', os: osx, language: objective-c} + - {osx_image: xcode8.3, env: 'SWFT=3.1 PLAT=iOS DST="OS=10.3.1,name=iPhone SE"', os: osx, language: objective-c} + - {osx_image: xcode8.3, env: 'SWFT=3.1 PLAT=tvOS DST="OS=10.2,name=Apple TV 1080p"', os: osx, language: objective-c} + - {osx_image: xcode8.3, env: 'SWFT=3.1 PLAT=macOS DST="arch=x86_64"', os: osx, language: objective-c} + - {osx_image: xcode8.3, env: 'SWFT=3.1 PLAT=watchOS DST="OS=3.2,name=Apple Watch - 38mm"', os: osx, language: objective-c} - - {osx_image: xcode9.2, env: 'PLAT=macOS SWFT=3.2 DST="arch=x86_64"', os: osx, language: objective-c} - - {osx_image: xcode9.2, env: 'PLAT=iOS SWFT=3.2 DST="OS=8.4,name=iPhone 4s"', os: osx, language: objective-c} - - {osx_image: xcode9.2, env: 'PLAT=iOS SWFT=3.2 DST="OS=9.3,name=iPhone SE"', os: osx, language: objective-c} - - {osx_image: xcode9.2, env: 'PLAT=iOS SWFT=3.2 DST="OS=10.3.1,name=iPhone SE"', os: osx, language: objective-c} - - {osx_image: xcode9.2, env: 'PLAT=iOS SWFT=3.2 DST="OS=11.2,name=iPhone SE"', os: osx, language: objective-c} - - {osx_image: xcode9.2, env: 'PLAT=tvOS SWFT=3.2 DST="OS=10.2,name=Apple TV 1080p"', os: osx, language: objective-c} - - {osx_image: xcode9.2, env: 'PLAT=tvOS SWFT=3.2 DST="OS=11.2,name=Apple TV 1080p"', os: osx, language: objective-c} - - {osx_image: xcode9.2, env: 'PLAT=watchOS SWFT=3.2 DST="OS=3.2,name=Apple Watch - 38mm"', os: osx, language: objective-c} - - {osx_image: xcode9.2, env: 'PLAT=watchOS SWFT=3.2 DST="OS=4.2,name=Apple Watch - 38mm"', os: osx, language: objective-c} + - {osx_image: xcode9.2, env: 'SWFT=3.2 PLAT=iOS DST="OS=11.2,name=iPhone SE"', os: osx, language: objective-c} + - {osx_image: xcode9.2, env: 'SWFT=3.2 PLAT=tvOS DST="OS=11.2,name=Apple TV 1080p"', os: osx, language: objective-c} + - {osx_image: xcode9.2, env: 'SWFT=3.2 PLAT=macOS DST="arch=x86_64"', os: osx, language: objective-c} + - {osx_image: xcode9.2, env: 'SWFT=3.2 PLAT=watchOS DST="OS=4.2,name=Apple Watch - 38mm"', os: osx, language: objective-c} - - {osx_image: xcode9.2, env: 'PLAT=macOS SWFT=4.0 DST="arch=x86_64"', os: osx, language: objective-c} - - {osx_image: xcode9.2, env: 'PLAT=iOS SWFT=4.0 DST="OS=8.4,name=iPhone 4s"', os: osx, language: objective-c} - - {osx_image: xcode9.2, env: 'PLAT=iOS SWFT=4.0 DST="OS=9.3,name=iPhone SE"', os: osx, language: objective-c} - - {osx_image: xcode9.2, env: 'PLAT=iOS SWFT=4.0 DST="OS=10.3.1,name=iPhone SE"', os: osx, language: objective-c} - - {osx_image: xcode9.2, env: 'PLAT=iOS SWFT=4.0 DST="OS=11.2,name=iPhone SE"', os: osx, language: objective-c} - - {osx_image: xcode9.2, env: 'PLAT=tvOS SWFT=4.0 DST="OS=10.2,name=Apple TV 1080p"', os: osx, language: objective-c} - - {osx_image: xcode9.2, env: 'PLAT=tvOS SWFT=4.0 DST="OS=11.2,name=Apple TV 1080p"', os: osx, language: objective-c} - - {osx_image: xcode9.2, env: 'PLAT=watchOS SWFT=4.0 DST="OS=2.2,name=Apple Watch - 38mm"', os: osx, language: objective-c} - - {osx_image: xcode9.2, env: 'PLAT=watchOS SWFT=4.0 DST="OS=3.2,name=Apple Watch - 38mm"', os: osx, language: objective-c} - - {osx_image: xcode9.2, env: 'PLAT=watchOS SWFT=4.0 DST="OS=4.2,name=Apple Watch - 38mm"', os: osx, language: objective-c} + - {osx_image: xcode9.3beta, env: 'SWFT=3.3 PLAT=iOS DST="OS=11.3,name=iPhone SE"', os: osx, language: objective-c} + - {osx_image: xcode9.3beta, env: 'SWFT=3.3 PLAT=tvOS DST="OS=11.3,name=Apple TV 1080p"', os: osx, language: objective-c} + - {osx_image: xcode9.3beta, env: 'SWFT=3.3 PLAT=macOS DST="arch=x86_64"', os: osx, language: objective-c} + - {osx_image: xcode9.3beta, env: 'SWFT=3.3 PLAT=watchOS DST="OS=4.3,name=Apple Watch - 38mm"', os: osx, language: objective-c} + + - {osx_image: xcode9.2, env: 'SWFT=4.0 PLAT=iOS DST="OS=8.4,name=iPhone 4s"', os: osx, language: objective-c} + - {osx_image: xcode9.2, env: 'SWFT=4.0 PLAT=iOS DST="OS=9.3,name=iPhone SE"', os: osx, language: objective-c} + - {osx_image: xcode9.2, env: 'SWFT=4.0 PLAT=iOS DST="OS=10.3.1,name=iPhone SE"', os: osx, language: objective-c} + - {osx_image: xcode9.2, env: 'SWFT=4.0 PLAT=iOS DST="OS=11.2,name=iPhone SE"', os: osx, language: objective-c} + - {osx_image: xcode9.2, env: 'SWFT=4.0 PLAT=tvOS DST="OS=10.2,name=Apple TV 1080p"', os: osx, language: objective-c} + - {osx_image: xcode9.2, env: 'SWFT=4.0 PLAT=tvOS DST="OS=11.2,name=Apple TV 1080p"', os: osx, language: objective-c} + - {osx_image: xcode9.2, env: 'SWFT=4.0 PLAT=macOS DST="arch=x86_64"', os: osx, language: objective-c} + - {osx_image: xcode9.2, env: 'SWFT=4.0 PLAT=watchOS DST="OS=2.2,name=Apple Watch - 38mm"', os: osx, language: objective-c} + - {osx_image: xcode9.2, env: 'SWFT=4.0 PLAT=watchOS DST="OS=3.2,name=Apple Watch - 38mm"', os: osx, language: objective-c} + - {osx_image: xcode9.2, env: 'SWFT=4.0 PLAT=watchOS DST="OS=4.2,name=Apple Watch - 38mm"', os: osx, language: objective-c} + + - {osx_image: xcode9.3beta, env: 'SWFT=4.1 PLAT=macOS DST="arch=x86_64"', os: osx, language: objective-c} + - {osx_image: xcode9.3beta, env: 'SWFT=4.1 PLAT=iOS DST="OS=11.3,name=iPhone SE"', os: osx, language: objective-c} + - {osx_image: xcode9.3beta, env: 'SWFT=4.1 PLAT=tvOS DST="OS=11.3,name=Apple TV 1080p"', os: osx, language: objective-c} + - {osx_image: xcode9.3beta, env: 'SWFT=4.1 PLAT=watchOS DST="OS=4.3,name=Apple Watch - 38mm"', os: osx, language: objective-c} - {os: linux, dist: trusty, sudo: required, services: docker, env: 'DOCKER_IMAGE=swift:3.1'} - #TODO please help us test Linux with Swift 3.0, 3.2 and 4.0 + - {os: linux, dist: trusty, sudo: required, services: docker, env: 'DOCKER_IMAGE=swift:4.0'} before_install: - if [ "$TRAVIS_OS_NAME" == "linux" ]; then @@ -40,8 +42,8 @@ script: - set -o pipefail - case $PLAT in iOS|tvOS|macOS) - xcodebuild -scheme PromiseKit -destination "$DST" -quiet build-for-testing SWIFT_VERSION=$SWFT -enableCodeCoverage YES | xcpretty; - xcodebuild -scheme PromiseKit -quiet test;; + xcodebuild -scheme PromiseKit SWIFT_VERSION=$SWFT -quiet build-for-testing -destination "$DST" -enableCodeCoverage YES | xcpretty; + xcodebuild -scheme PromiseKit SWIFT_VERSION=$SWFT -quiet test;; watchOS) xcodebuild -scheme PromiseKit -destination "$DST" -quiet build SWIFT_VERSION=$SWFT | xcpretty;; *) diff --git a/Documentation/CommonPatterns.md b/Documentation/CommonPatterns.md index 81539a970..ba16c1a54 100644 --- a/Documentation/CommonPatterns.md +++ b/Documentation/CommonPatterns.md @@ -128,7 +128,7 @@ avoiding throwing an error because you can’t be bothered to define a good glob ## Abstracting Away Asychronicity -```switch +```swift var fetch = API.fetch() override func viewDidAppear() { @@ -288,10 +288,10 @@ func attempt(interdelay: DispatchTimeInterval = .seconds(2), maxRepeat: Int = var attempts = 0 func attempt() -> Promise { attempts += 1 - return body().recover { error in + return body().recover { error -> Promise in guard attempts < maxRepeat else { throw error } - return after(interval: interdelay).then { + return after(interdelay).then { attempt() } } @@ -370,7 +370,7 @@ CLLocationManager.promise().then { locations in Sometimes you don’t want an error to cascade, instead you have a default value: -``` +```swift CLLocationManager.promise().recover { error -> CLLocation in guard error == MyError.airplaneMode else { throw error diff --git a/Documentation/Installation.md b/Documentation/Installation.md index b4c383593..b866d1073 100644 --- a/Documentation/Installation.md +++ b/Documentation/Installation.md @@ -45,14 +45,14 @@ You can just drop `PromiseKit.xcodeproj` into your project and then add PromiseKit contains Swift, so there have been rev-lock issues with Xcode: -| PromiseKit | Swift | Xcode | CI Status | Release Notes | -| ---------- | -------- | -------- | ------------ | ----------------- | -| 6 | 3.x, 4.x | 8.x, 9.x | ![ci-master] | [2018/02][news-6] | -| 5 | 3.x, 4.x | 8.x, 9.x | ![ci-master] | *Deprecated* | -| 4 | 3.x, 4.x | 8.x, 9.x | ![ci-master] | [2016/09][news-4] | -| 3 | 2.x | 7.x, 8.0 | ![ci-swift2] | [2015/10][news-3] | -| 2 | 1.x | 7.x | Unsupported | [2015/10][news-3] | -| 1† | *N/A* | * | ![ci-legacy] | – | +| PromiseKit | Swift | Xcode | CI Status | Release Notes | +| ---------- | ----------------------- | -------- | ------------ | ----------------- | +| 6 | 3.1, 3.2, 3.3, 4.x | 8.3, 9.x | ![ci-master] | [2018/02][news-6] | +| 5 | 3.1, 3.2, 3.3, 4.x | 8.3, 9.x | *Deprecated* | *n/a* | +| 4 | 3.0, 3.1, 3.2, 3.3, 4.x | 8.x, 9.x | ![ci-master] | [2016/09][news-4] | +| 3 | 2.x | 7.x, 8.0 | ![ci-swift2] | [2015/10][news-3] | +| 2 | 1.x | 7.x | *Deprecated* | [2015/10][news-3] | +| 1† | *N/A* | * | ![ci-legacy] | – | † PromiseKit 1 is pure Objective-C and thus can be used with any Xcode, it is @@ -149,9 +149,13 @@ Then when you `pod update`, ensure you also update your submodules: # Release History +## [6.0](https://github.com/mxcl/PromiseKit/releases/tag/6.0.0) Feb 13th, 2019 + +* [PromiseKit 4 announcement post][news-6]. + ## [4.0](https://github.com/mxcl/PromiseKit/releases/tag/4.0.0) -* [PromiseKit 4 announcement post](http://promisekit.org/news/2016/09/PromiseKit-4.0-Released/). +* [PromiseKit 4 announcement post][news-4]. ## [3.0](https://github.com/mxcl/PromiseKit/releases/tag/3.0.0) Oct 1st, 2015 diff --git a/PromiseKit.xcodeproj/project.pbxproj b/PromiseKit.xcodeproj/project.pbxproj index 3ce993826..6b043d408 100644 --- a/PromiseKit.xcodeproj/project.pbxproj +++ b/PromiseKit.xcodeproj/project.pbxproj @@ -515,7 +515,7 @@ 6399A3721D595D9100D65233 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0900; + LastUpgradeCheck = 0930; TargetAttributes = { 630019011D596292003B4E30 = { LastSwiftMigration = 0900; @@ -785,12 +785,14 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -799,7 +801,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 6.0.1; + CURRENT_PROJECT_VERSION = 6.0.2; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -808,6 +810,7 @@ GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1"; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNDECLARED_SELECTOR = YES; @@ -825,7 +828,7 @@ SUPPORTED_PLATFORMS = "macosx appletvsimulator appletvos watchsimulator iphonesimulator watchos iphoneos"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; TVOS_DEPLOYMENT_TARGET = 9.0; VERSIONING_SYSTEM = "apple-generic"; WATCHOS_DEPLOYMENT_TARGET = 2.0; @@ -843,12 +846,14 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -857,13 +862,14 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 6.0.1; + CURRENT_PROJECT_VERSION = 6.0.2; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNDECLARED_SELECTOR = YES; @@ -879,7 +885,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "macosx appletvsimulator appletvos watchsimulator iphonesimulator watchos iphoneos"; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; TVOS_DEPLOYMENT_TARGET = 9.0; VERSIONING_SYSTEM = "apple-generic"; WATCHOS_DEPLOYMENT_TARGET = 2.0; diff --git a/PromiseKit.xcodeproj/xcshareddata/xcschemes/PromiseKit.xcscheme b/PromiseKit.xcodeproj/xcshareddata/xcschemes/PromiseKit.xcscheme index a75458f28..54204da52 100644 --- a/PromiseKit.xcodeproj/xcshareddata/xcschemes/PromiseKit.xcscheme +++ b/PromiseKit.xcodeproj/xcshareddata/xcschemes/PromiseKit.xcscheme @@ -1,6 +1,6 @@ ) -> Void) @@ -181,10 +174,10 @@ public extension Thenable where T: Sequence { func compactMap(on: DispatchQueue? = conf.Q.map, _ transform: @escaping(T.Iterator.Element) throws -> U?) -> Promise<[U]> { return map(on: on) { foo -> [U] in - #if swift(>=4.1) - return try foo.compactMap(transform) } - #else + #if !swift(>=3.3) || (swift(>=4) && !swift(>=4.1)) return try foo.flatMap(transform) + #else + return try foo.compactMap(transform) #endif } } diff --git a/Sources/when.swift b/Sources/when.swift index f031d96aa..59884cd2d 100644 --- a/Sources/when.swift +++ b/Sources/when.swift @@ -170,7 +170,11 @@ public func when(fulfilled promiseIterator: It, concurrent func testDone() { barrier.sync { if pendingPromises == 0 { + #if !swift(>=3.3) || (swift(>=4) && !swift(>=4.1)) root.resolver.fulfill(promises.flatMap{ $0.value }) + #else + root.resolver.fulfill(promises.compactMap{ $0.value }) + #endif } } } diff --git a/Tests/A+/0.0.0.swift b/Tests/A+/0.0.0.swift index eddf5d24c..c31ce3050 100644 --- a/Tests/A+/0.0.0.swift +++ b/Tests/A+/0.0.0.swift @@ -25,7 +25,7 @@ extension XCTestCase { let (pending, seal) = Promise.pending() do { - try body((pending, seal.fulfill, seal.reject), expectation) + try body((pending, { seal.fulfill(()) }, seal.reject), expectation) waitForExpectations(timeout: timeout) { err in if let _ = err { XCTFail("wait failed: \(description)", file: file, line: line)