Skip to content

Commit

Permalink
Require Xcode 16 or later
Browse files Browse the repository at this point in the history
This means:

- using it for development (which will allow us to use Swift Testing,
  which we’ll do in #55)

- requiring users of the library to use it (so that we can use Swift 6
  features, which we’ll do in #56) — we’ve decided we’re happy to do
  this since from April 2025 Apple will force users wishing to upload to
  the App Store to use it anyway

Whilst implementing this, I decided to revisit my comment from
646c220:

> I haven’t committed the `.swiftpm/configuration/Package.resolved` file
> created by Xcode 16. We already have two Package.resolved files (see the
> `comparePackageLockfiles` lint task) and so let’s wait for Xcode 16 to
> be released to see whether this file is going to stick around (perhaps
> it will become part of the .gitignore created by the SPM that ships with
> Xcode 16).

With the release version of Xcode 16, I am no longer able to get Xcode
to generate this file, so either they changed something or it’s going to
reappear at some point when we poke Xcode in some very specific way (at
which point we can decide what to do with it).

Resolves #21.
  • Loading branch information
lawrence-forooghian committed Sep 18, 2024
1 parent 70592d5 commit 67f4563
Show file tree
Hide file tree
Showing 7 changed files with 15 additions and 108 deletions.
11 changes: 11 additions & 0 deletions .github/workflows/check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ jobs:
steps:
- uses: actions/checkout@v4

# This step can be removed once the runners’ default version of Xcode is 16 or above
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: 16

# We use caching for Mint because at the time of writing SwiftLint took about 5 minutes to build in CI, which is unacceptably slow.
# https://github.com/actions/cache/blob/40c3b67b2955d93d83b27ed164edd0756bc24049/examples.md#swift---mint
- uses: actions/cache@v4
Expand All @@ -39,6 +44,12 @@ jobs:
matrix: ${{ steps.generation-step.outputs.matrix }}
steps:
- uses: actions/checkout@v4

# This step can be removed once the runners’ default version of Xcode is 16 or above
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: 16

- id: generation-step
run: swift run BuildTool generate-matrices >> $GITHUB_OUTPUT

Expand Down
2 changes: 1 addition & 1 deletion .swift-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5.10
6.0
17 changes: 0 additions & 17 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,3 @@ To check formatting and code quality, run `swift run BuildTool lint`. Run with `
- We should aim to make it easy for consumers of the SDK to be able to mock out the SDK in the tests for their own code. A couple of things that will aid with this:
- Describe the SDK’s functionality via protocols (when doing so would still be sufficiently idiomatic to Swift).
- When defining a `struct` that is emitted by the public API of the library, make sure to define a public memberwise initializer so that users can create one to be emitted by their mocks. (There is no way to make Swift’s autogenerated memberwise initializer public, so you will need to write one yourself. In Xcode, you can do this by clicking at the start of the type declaration and doing Editor → Refactor → Generate Memberwise Initializer.)

## Building for Swift 6

At the time of writing (August 2024), the latest version of Swift to ship with a release version of Xcode is Swift 5.10. However, in the next few months Apple will launch Swift 6, which refines the strict concurrency checking introduced in Swift 5.10. Specifically, my understanding is that it introduces features that make Swift 5.10’s strict concurrency checking more developer-friendly. I think that some of these features can be switched on in Swift 5.10, but I’m not sure if all of them can. So, Swift 6 releases we might decide that we want to switch to using Swift 6 for our SDK. So, in CI, in addition to Swift 5 language mode, we also try building the SDK in Swift 6 language mode using the latest Xcode 16 beta.

And, actually more importantly, we want to be sure that the SDK can be integrated into a user’s application that uses Swift 6. So, in CI, in addition to Swift 5 language mode, we also try building the example app in Swift 6 language mode using the aforementioned Xcode beta.

(If any of the above turns out to cause a lot of problems due to the quality of the beta software, we can reconsider this.)

### Multiple `Package.swift` files

We have a separate manifest file, `[email protected]`, which a Swift compiler supporting Swift 6 will use instead of `Package.swift` (see [documentation of this SPM feature](https://github.com/swiftlang/swift-package-manager/blob/74f06f8a7fd6b4c729e474dee34db66319d90759/Documentation/Usage.md#version-specific-manifest-selection)). This file exists for two reasons:

1. To tell the compiler “use the Swift 6 language mode to compile this package if the compiler supports Swift 6, else use the Swift 5 language mode” (I previously tried passing `-Xswiftc -swift-version -Xswiftc 6` to `swift build` but this seems to then use Swift 6 language mode for compiling not just our own package, but all of our dependencies, which is likely to fail.)
2. If you try to use `.enableUpcomingFeature` for a feature that is enabled by default in Swift 6, you’ll get an error `error: upcoming feature 'BareSlashRegexLiterals' is already enabled as of Swift version 6`. (I don’t know if there’s a better way of handling this.)

So, we need to make sure we keep `Package.swift` and `[email protected]` in sync manually.
21 changes: 1 addition & 20 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version: 5.10
// swift-tools-version: 6.0

import PackageDescription

Expand Down Expand Up @@ -39,20 +39,6 @@ let package = Package(
name: "Ably",
package: "ably-cocoa"
),
],
swiftSettings: [
// We build with strict concurrency checking enabled, because:
//
// 1. in theory it’s a useful language feature that reduces
// bugs
// 2. it will be unavoidable if we migrate to Swift 6, so let’s
// future-proof ourselves
//
// This is the first time that I’ll have used strict
// concurrency checking, so I don’t know what kind of impact it
// might have; I’ve seen anecdotes that it can make developers’
// lives tricky.
.enableExperimentalFeature("StrictConcurrency"),
]
),
.testTarget(
Expand All @@ -76,11 +62,6 @@ let package = Package(
name: "AsyncAlgorithms",
package: "swift-async-algorithms"
),
],
swiftSettings: [
// See justification above.
.enableExperimentalFeature("StrictConcurrency"),
.enableUpcomingFeature("BareSlashRegexLiterals"),
]
),
]
Expand Down
68 changes: 0 additions & 68 deletions [email protected]

This file was deleted.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ This is the repository for the Swift version of the Ably Chat SDK. We aim to bui

## Requirements

Xcode 15.3 (i.e. a compiler that supports Swift 5.10) or later.
Xcode 16 (i.e. a compiler that supports Swift 6) or later.

## Installation

Expand Down
2 changes: 1 addition & 1 deletion Sources/BuildTool/BuildTool.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ struct GenerateMatrices: ParsableCommand {
mutating func run() throws {
let tooling = [
[
"xcodeVersion": "15.3",
"xcodeVersion": "16",
"swiftVersion": 5,
],
[
Expand Down

0 comments on commit 67f4563

Please sign in to comment.