diff --git a/.github/workflows/vertexai.yml b/.github/workflows/vertexai.yml index de39aecf7fa..2b08ca897df 100644 --- a/.github/workflows/vertexai.yml +++ b/.github/workflows/vertexai.yml @@ -47,22 +47,22 @@ jobs: xcode: Xcode_16.2 target: iOS - os: macos-15 - xcode: Xcode_16.2 + xcode: Xcode_16.3 target: iOS - os: macos-15 - xcode: Xcode_16.2 + xcode: Xcode_16.3 target: tvOS - os: macos-15 - xcode: Xcode_16.2 + xcode: Xcode_16.3 target: macOS - os: macos-15 - xcode: Xcode_16.2 + xcode: Xcode_16.3 target: watchOS - os: macos-15 - xcode: Xcode_16.2 + xcode: Xcode_16.3 target: catalyst - os: macos-15 - xcode: Xcode_16.2 + xcode: Xcode_16.3 target: visionOS runs-on: ${{ matrix.os }} needs: spm-package-resolved @@ -98,7 +98,7 @@ jobs: os: [macos-15] include: - os: macos-15 - xcode: Xcode_16.2 + xcode: Xcode_16.3 runs-on: ${{ matrix.os }} needs: spm-package-resolved env: @@ -137,11 +137,11 @@ jobs: swift_version: 5.9 warnings: - os: macos-15 - xcode: Xcode_16.2 + xcode: Xcode_16.3 swift_version: 5.9 warnings: - os: macos-15 - xcode: Xcode_16.2 + xcode: Xcode_16.3 swift_version: 6.0 warnings: runs-on: ${{ matrix.os }} diff --git a/FirebaseVertexAI/CHANGELOG.md b/FirebaseVertexAI/CHANGELOG.md index 1227c56065e..936109166d0 100644 --- a/FirebaseVertexAI/CHANGELOG.md +++ b/FirebaseVertexAI/CHANGELOG.md @@ -8,6 +8,8 @@ change in backwards-incompatible ways. - [added] Added support for specifying the minimum and maximum number of items (`minItems` / `maxItems`) to generate in an array `Schema`. (#14671) +- [fixed] Fixed an issue where network requests would fail in the iOS 18.4 + simulator due to a `URLSession` bug introduced in Xcode 16.3. (#14677) # 11.11.0 - [added] Emits a warning when attempting to use an incompatible model with diff --git a/FirebaseVertexAI/Sources/GenAIURLSession.swift b/FirebaseVertexAI/Sources/GenAIURLSession.swift new file mode 100644 index 00000000000..39a45ca55d3 --- /dev/null +++ b/FirebaseVertexAI/Sources/GenAIURLSession.swift @@ -0,0 +1,38 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import Foundation + +/// A namespace providing `URLSession` instances. +enum GenAIURLSession { + /// The default `URLSession` instance for the SDK; returns `URLSession.shared` by default. + /// + /// - Important: On affected simulators (iOS 18.4+, visionOS 2.4+), this returns an ephemeral + /// `URLSession` instance as a workaround for a known system bug. + static let `default` = { + #if targetEnvironment(simulator) + // The iOS 18.4 and visionOS 2.4 simulators (included in Xcode 16.3) contain a bug in + // `URLSession` causing requests to fail. The following workaround, using an ephemeral session + // resolves the issue. See https://developer.apple.com/forums/thread/777999 for more details. + // + // Note: This bug only impacts the simulator, not real devices, and does not impact watchOS + // or tvOS. + if #available(iOS 18.4, tvOS 100.0, watchOS 100.0, visionOS 2.4, *) { + return URLSession(configuration: URLSessionConfiguration.ephemeral) + } + #endif // targetEnvironment(simulator) + + return URLSession.shared + }() +} diff --git a/FirebaseVertexAI/Sources/GenerativeModel.swift b/FirebaseVertexAI/Sources/GenerativeModel.swift index 4714e78f1ef..c601c2e1aee 100644 --- a/FirebaseVertexAI/Sources/GenerativeModel.swift +++ b/FirebaseVertexAI/Sources/GenerativeModel.swift @@ -83,7 +83,7 @@ public final class GenerativeModel: Sendable { toolConfig: ToolConfig? = nil, systemInstruction: ModelContent? = nil, requestOptions: RequestOptions, - urlSession: URLSession = .shared) { + urlSession: URLSession = GenAIURLSession.default) { self.modelName = modelName self.modelResourceName = modelResourceName self.apiConfig = apiConfig diff --git a/FirebaseVertexAI/Sources/Types/Public/Imagen/ImagenModel.swift b/FirebaseVertexAI/Sources/Types/Public/Imagen/ImagenModel.swift index 90e5bb9f715..a829f616773 100644 --- a/FirebaseVertexAI/Sources/Types/Public/Imagen/ImagenModel.swift +++ b/FirebaseVertexAI/Sources/Types/Public/Imagen/ImagenModel.swift @@ -53,7 +53,7 @@ public final class ImagenModel { generationConfig: ImagenGenerationConfig?, safetySettings: ImagenSafetySettings?, requestOptions: RequestOptions, - urlSession: URLSession = .shared) { + urlSession: URLSession = GenAIURLSession.default) { self.modelResourceName = modelResourceName self.apiConfig = apiConfig generativeAIService = GenerativeAIService( diff --git a/FirebaseVertexAI/Sources/VertexAI.swift b/FirebaseVertexAI/Sources/VertexAI.swift index 112d117047d..c3ef7d2df73 100644 --- a/FirebaseVertexAI/Sources/VertexAI.swift +++ b/FirebaseVertexAI/Sources/VertexAI.swift @@ -18,7 +18,7 @@ import FirebaseCore import Foundation // Avoids exposing internal FirebaseCore APIs to Swift users. -@_implementationOnly import FirebaseCoreExtension +internal import FirebaseCoreExtension /// The Vertex AI for Firebase SDK provides access to Gemini models directly from your app. @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *) diff --git a/FirebaseVertexAI/Sources/VertexLog.swift b/FirebaseVertexAI/Sources/VertexLog.swift index ff94a2d435e..b98ed0f50f2 100644 --- a/FirebaseVertexAI/Sources/VertexLog.swift +++ b/FirebaseVertexAI/Sources/VertexLog.swift @@ -15,7 +15,7 @@ import Foundation import os.log -@_implementationOnly import FirebaseCoreExtension +internal import FirebaseCoreExtension enum VertexLog { /// Log message codes for the Vertex AI SDK diff --git a/FirebaseVertexAI/Tests/Unit/GenerativeModelTests.swift b/FirebaseVertexAI/Tests/Unit/GenerativeModelTests.swift index 290238445c5..8dd2cf07e42 100644 --- a/FirebaseVertexAI/Tests/Unit/GenerativeModelTests.swift +++ b/FirebaseVertexAI/Tests/Unit/GenerativeModelTests.swift @@ -17,7 +17,7 @@ import FirebaseAuthInterop import FirebaseCore import XCTest -@testable import FirebaseVertexAI +@testable public import FirebaseVertexAI @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *) final class GenerativeModelTests: XCTestCase { @@ -1690,8 +1690,7 @@ struct AppCheckErrorFake: Error {} @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *) extension SafetyRating: Swift.Comparable { - public static func < (lhs: FirebaseVertexAI.SafetyRating, - rhs: FirebaseVertexAI.SafetyRating) -> Bool { + public static func < (lhs: SafetyRating, rhs: SafetyRating) -> Bool { return lhs.category.rawValue < rhs.category.rawValue } } diff --git a/FirebaseVertexAI/Tests/Unit/VertexComponentTests.swift b/FirebaseVertexAI/Tests/Unit/VertexComponentTests.swift index 6535ba26137..3f9f6622ead 100644 --- a/FirebaseVertexAI/Tests/Unit/VertexComponentTests.swift +++ b/FirebaseVertexAI/Tests/Unit/VertexComponentTests.swift @@ -13,11 +13,10 @@ // limitations under the License. @preconcurrency import FirebaseCore +internal import FirebaseCoreExtension import Foundation import XCTest -@_implementationOnly import FirebaseCoreExtension - @testable import FirebaseVertexAI @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)