diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml index 843c3b42..142defe4 100644 --- a/.github/workflows/ios.yml +++ b/.github/workflows/ios.yml @@ -19,8 +19,9 @@ concurrency: cancel-in-progress: true jobs: + # Xcode 27.1+ is required: the app uses iOS 27.1 SDK APIs (e.g. UIHingeInteraction). package-tests: - runs-on: macos-15 + runs-on: xcode-27 steps: - uses: actions/checkout@v4 - name: Show toolchain versions @@ -31,7 +32,7 @@ jobs: run: swift test --package-path ios/Packages/HapiKit app-build: - runs-on: macos-15 + runs-on: xcode-27 steps: - uses: actions/checkout@v4 - name: Show toolchain versions diff --git a/docs/guide/native-apps.md b/docs/guide/native-apps.md index 893e7828..712bd51f 100644 --- a/docs/guide/native-apps.md +++ b/docs/guide/native-apps.md @@ -22,7 +22,7 @@ or Apple developer setup is needed on your hub. See [Notifications](#notificatio ### Build from source (developers) The app source is in the repository. Development builds follow the -[iOS README](https://github.com/tiann/hapi/blob/main/ios/README.md) (Xcode 16 +[iOS README](https://github.com/tiann/hapi/blob/main/ios/README.md) (Xcode 27.1 or newer, shared `Hapi` scheme; device builds require signing) or the [Android README](https://github.com/tiann/hapi/blob/main/android/README.md) (JDK 17+, Android SDK, Gradle wrapper). Self-built apps need their own push diff --git a/ios/Packages/HapiKit/Tests/HapiClientTests/MultipartEncoderTests.swift b/ios/Packages/HapiKit/Tests/HapiClientTests/MultipartEncoderTests.swift index e4fb4b44..18ada527 100644 --- a/ios/Packages/HapiKit/Tests/HapiClientTests/MultipartEncoderTests.swift +++ b/ios/Packages/HapiKit/Tests/HapiClientTests/MultipartEncoderTests.swift @@ -15,18 +15,19 @@ struct MultipartEncoderTests { data: Data([0x01, 0x02]) ) + // Joined rather than `+`-chained: Swift 6.4 times out type-checking the chain. var expected = Data( - ( - "--B\r\n" - + "Content-Disposition: form-data; name=\"provider\"\r\n\r\n" - + "openai\r\n" - + "--B\r\n" - + "Content-Disposition: form-data; name=\"mode\"\r\n\r\n" - + "standard\r\n" - + "--B\r\n" - + "Content-Disposition: form-data; name=\"file\"; filename=\"clip.m4a\"\r\n" - + "Content-Type: audio/mp4\r\n\r\n" - ).utf8 + [ + "--B\r\n", + "Content-Disposition: form-data; name=\"provider\"\r\n\r\n", + "openai\r\n", + "--B\r\n", + "Content-Disposition: form-data; name=\"mode\"\r\n\r\n", + "standard\r\n", + "--B\r\n", + "Content-Disposition: form-data; name=\"file\"; filename=\"clip.m4a\"\r\n", + "Content-Type: audio/mp4\r\n\r\n", + ].joined().utf8 ) expected.append(Data([0x01, 0x02])) expected.append(Data("\r\n--B--\r\n".utf8)) diff --git a/ios/README.md b/ios/README.md index 362f3027..2cce8f20 100644 --- a/ios/README.md +++ b/ios/README.md @@ -26,7 +26,8 @@ for platform differences, web-only features and everyday use. ## Requirements -- Xcode 16 or newer with Swift 6 support. +- Xcode 27.1 or newer (the app uses iOS 27.1 SDK APIs such as + `UIHingeInteraction`). - Deployment target: iOS 17.0. - Runtime dependencies (SPM, declared in `Packages/HapiKit/Package.swift`, used only by the `HapiUI` target): `swiftlang/swift-markdown` (GFM parsing @@ -52,8 +53,8 @@ swift test --package-path ios/Packages/HapiKit ``` CI runs package tests, the simulator build, and app-hosted transcript tests -on `macos-15` via `.github/workflows/ios.yml` (triggered by changes under -`ios/**` and `shared/fixtures/**`). +on the `xcode-27` runner image via `.github/workflows/ios.yml` (triggered by +changes under `ios/**` and `shared/fixtures/**`). ### Linux verification (no Mac needed)