Browse Source

[Firebase AI] Rename module to `FirebaseAILogic` (#15275)

Andrew Heard 5 months ago
parent
commit
a98ea60233
60 changed files with 493 additions and 76 deletions
  1. 8 2
      .github/workflows/firebaseai.yml
  2. 51 0
      .github/workflows/zip.yml
  3. 3 12
      FirebaseAI.podspec
  4. 2 2
      FirebaseAI/Tests/TestApp/Tests/Integration/CountTokensIntegrationTests.swift
  5. 2 2
      FirebaseAI/Tests/TestApp/Tests/Integration/GenerateContentIntegrationTests.swift
  6. 2 2
      FirebaseAI/Tests/TestApp/Tests/Integration/ImagenIntegrationTests.swift
  7. 2 2
      FirebaseAI/Tests/TestApp/Tests/Integration/IntegrationTests.swift
  8. 2 2
      FirebaseAI/Tests/TestApp/Tests/Integration/LiveSessionTests.swift
  9. 2 2
      FirebaseAI/Tests/TestApp/Tests/Integration/SchemaTests.swift
  10. 2 2
      FirebaseAI/Tests/TestApp/Tests/Utilities/InstanceConfig.swift
  11. 1 1
      FirebaseAI/Tests/Unit/APITests.swift
  12. 1 1
      FirebaseAI/Tests/Unit/ChatTests.swift
  13. 1 1
      FirebaseAI/Tests/Unit/GenerationConfigTests.swift
  14. 1 1
      FirebaseAI/Tests/Unit/GenerativeModelGoogleAITests.swift
  15. 1 1
      FirebaseAI/Tests/Unit/GenerativeModelVertexAITests.swift
  16. 1 1
      FirebaseAI/Tests/Unit/JSONValueTests.swift
  17. 1 1
      FirebaseAI/Tests/Unit/PartTests.swift
  18. 1 1
      FirebaseAI/Tests/Unit/PartsRepresentableTests.swift
  19. 1 1
      FirebaseAI/Tests/Unit/RequestOptionsTest.swift
  20. 1 1
      FirebaseAI/Tests/Unit/SafetyTests.swift
  21. 1 1
      FirebaseAI/Tests/Unit/Snippets/ChatSnippets.swift
  22. 1 1
      FirebaseAI/Tests/Unit/Snippets/CloudStorageSnippets.swift
  23. 1 1
      FirebaseAI/Tests/Unit/Snippets/CountTokensSnippets.swift
  24. 1 1
      FirebaseAI/Tests/Unit/Snippets/FunctionCallingSnippets.swift
  25. 1 1
      FirebaseAI/Tests/Unit/Snippets/LiveSnippets.swift
  26. 1 1
      FirebaseAI/Tests/Unit/Snippets/MultimodalSnippets.swift
  27. 1 1
      FirebaseAI/Tests/Unit/Snippets/StructuredOutputSnippets.swift
  28. 1 1
      FirebaseAI/Tests/Unit/Snippets/TextSnippets.swift
  29. 1 1
      FirebaseAI/Tests/Unit/TestUtilities/FirebaseAI+DefaultAPIConfig.swift
  30. 1 1
      FirebaseAI/Tests/Unit/TestUtilities/GenerativeModelTestUtil.swift
  31. 1 1
      FirebaseAI/Tests/Unit/Types/BackendTests.swift
  32. 1 1
      FirebaseAI/Tests/Unit/Types/CitationMetadataTests.swift
  33. 1 1
      FirebaseAI/Tests/Unit/Types/CitationTests.swift
  34. 1 1
      FirebaseAI/Tests/Unit/Types/GenerateContentResponseTests.swift
  35. 1 1
      FirebaseAI/Tests/Unit/Types/GroundingMetadataTests.swift
  36. 1 1
      FirebaseAI/Tests/Unit/Types/Imagen/ImageGenerationInstanceTests.swift
  37. 1 1
      FirebaseAI/Tests/Unit/Types/Imagen/ImageGenerationOutputOptionsTests.swift
  38. 1 1
      FirebaseAI/Tests/Unit/Types/Imagen/ImageGenerationParametersTests.swift
  39. 1 1
      FirebaseAI/Tests/Unit/Types/Imagen/ImagenGCSImageTests.swift
  40. 1 1
      FirebaseAI/Tests/Unit/Types/Imagen/ImagenGenerationRequestTests.swift
  41. 1 1
      FirebaseAI/Tests/Unit/Types/Imagen/ImagenGenerationResponseTests.swift
  42. 1 1
      FirebaseAI/Tests/Unit/Types/Imagen/ImagenInlineImageTests.swift
  43. 1 1
      FirebaseAI/Tests/Unit/Types/Imagen/RAIFilteredReasonTests.swift
  44. 1 1
      FirebaseAI/Tests/Unit/Types/Internal/APIConfigTests.swift
  45. 1 1
      FirebaseAI/Tests/Unit/Types/Internal/Requests/CountTokensRequestTests.swift
  46. 1 1
      FirebaseAI/Tests/Unit/Types/InternalPartTests.swift
  47. 1 1
      FirebaseAI/Tests/Unit/Types/ModalityTokenCountTests.swift
  48. 1 1
      FirebaseAI/Tests/Unit/Types/ProtoDateTests.swift
  49. 1 1
      FirebaseAI/Tests/Unit/Types/ProtoDurationTests.swift
  50. 1 1
      FirebaseAI/Tests/Unit/Types/SchemaTests.swift
  51. 1 1
      FirebaseAI/Tests/Unit/Types/ToolTests.swift
  52. 1 1
      FirebaseAI/Tests/Unit/VertexComponentTests.swift
  53. 15 0
      FirebaseAI/Wrapper/Sources/FirebaseAIWrapper.swift
  54. 186 0
      FirebaseAI/Wrapper/Tests/APITests.swift
  55. 70 0
      FirebaseAILogic.podspec
  56. 23 4
      Package.swift
  57. 1 0
      ReleaseTooling/CarthageJSON/FirebaseAILogicBinary.json
  58. 2 1
      ReleaseTooling/Sources/FirebaseManifest/FirebaseManifest.swift
  59. 77 0
      scripts/spm_test_schemes/FirebaseAILogicUnit.xcscheme
  60. 1 1
      scripts/zip_quickstart_test.sh

+ 8 - 2
.github/workflows/firebaseai.yml

@@ -27,9 +27,12 @@ permissions:
 
 jobs:
   spm:
+    strategy:
+      matrix:
+        target: [FirebaseAILogicUnit, FirebaseAIUnit]
     uses: ./.github/workflows/common.yml
     with:
-      target: FirebaseAIUnit
+      target: ${{  matrix.target }}
       setup_command: scripts/update_vertexai_responses.sh
 
   testapp-integration:
@@ -77,9 +80,12 @@ jobs:
         retention-days: 2
 
   pod_lib_lint:
+    strategy:
+      matrix:
+        product: [FirebaseAILogic, FirebaseAI]
     uses: ./.github/workflows/common_cocoapods.yml
     with:
-      product: FirebaseAI
+      product: ${{  matrix.product }}
       supports_swift6: true
       setup_command: scripts/update_vertexai_responses.sh
 

+ 51 - 0
.github/workflows/zip.yml

@@ -398,6 +398,57 @@ jobs:
         name: quickstart_artifacts database
         path: quickstart-ios/
 
+  quickstart_framework_firebaseai:
+    needs: package-head
+    if: ${{ !cancelled() && (success() || github.event.inputs.zip_run_id != '') }}
+    env:
+      plist_secret: ${{ secrets.GHASecretsGPGPassphrase1 }}
+      SDK: "FirebaseAI"
+      # This is a workaround to use the FirebaseAIExampleZip scheme that does not have the SPM dependency.
+      SWIFT_SUFFIX: "Zip"
+    strategy:
+      matrix:
+        artifact: [Firebase-actions-dir, Firebase-actions-dir-dynamic]
+        build-env:
+          - os: macos-15
+            xcode: Xcode_16.4
+    runs-on: ${{ matrix.build-env.os }}
+    steps:
+    - uses: actions/checkout@v4
+    - name: Get framework dir
+      uses: actions/download-artifact@v4.1.7
+      with:
+        name: ${{ matrix.artifact }}
+        run-id: ${{ github.event.inputs.zip_run_id || github.run_id }}
+        github-token: ${{ secrets.GITHUB_TOKEN }}
+    - uses: ruby/setup-ruby@354a1ad156761f5ee2b7b13fa8e09943a5e8d252 # v1
+    - name: Xcode
+      run: sudo xcode-select -s /Applications/${{ matrix.build-env.xcode }}.app/Contents/Developer
+    - name: Setup Bundler
+      run: ./scripts/setup_bundler.sh
+    - name: Move frameworks
+      run: |
+        mkdir -p "${HOME}"/ios_frameworks/
+        find "${GITHUB_WORKSPACE}" -name "Firebase*latest.zip" -exec unzip -d "${HOME}"/ios_frameworks/ {} +
+    - uses: actions/checkout@v4
+    - name: Setup quickstart
+      run: SAMPLE="$SDK" TARGET="${SDK}ExampleZip" scripts/setup_quickstart_framework.sh \
+                                               "${HOME}"/ios_frameworks/Firebase/FirebaseAILogic/* \
+                                               "${HOME}"/ios_frameworks/Firebase/FirebaseAnalytics/*
+    - name: Install Secret GoogleService-Info.plist
+      run: scripts/decrypt_gha_secret.sh scripts/gha-encrypted/FirebaseAI/TestApp-GoogleService-Info.plist.gpg \
+        quickstart-ios/firebaseai/GoogleService-Info.plist "$plist_secret"
+    - name: Test Quickstart
+      run: ([ -z $plist_secret ] || scripts/third_party/travis/retry.sh scripts/test_quickstart_framework.sh "${SDK}")
+    - name: Remove data before upload
+      if: ${{ failure() }}
+      run: scripts/remove_data.sh firebaseai
+    - uses: actions/upload-artifact@v4
+      if: ${{ failure() }}
+      with:
+        name: quickstart_artifacts_firebaseai
+        path: quickstart-ios/
+
   quickstart_framework_firestore:
     needs: package-head
     if: ${{ !cancelled() && (success() || github.event.inputs.zip_run_id != '') }}

+ 3 - 12
FirebaseAI.podspec

@@ -32,7 +32,7 @@ Build AI-powered apps and features with the Gemini API using the Firebase AI SDK
   s.prefix_header_file = false
 
   s.source_files = [
-    'FirebaseAI/Sources/**/*.swift',
+    'FirebaseAI/Wrapper/Sources/**/*.swift',
   ]
 
   s.swift_version = '5.9'
@@ -43,13 +43,11 @@ Build AI-powered apps and features with the Gemini API using the Firebase AI SDK
   s.tvos.framework = 'UIKit'
   s.watchos.framework = 'WatchKit'
 
-  s.dependency 'FirebaseAppCheckInterop', '~> 12.5.0'
-  s.dependency 'FirebaseAuthInterop', '~> 12.5.0'
+  s.dependency 'FirebaseAILogic', '12.5.0'
   s.dependency 'FirebaseCore', '~> 12.5.0'
-  s.dependency 'FirebaseCoreExtension', '~> 12.5.0'
 
   s.test_spec 'unit' do |unit_tests|
-    unit_tests_dir = 'FirebaseAI/Tests/Unit/'
+    unit_tests_dir = 'FirebaseAI/Wrapper/Tests/'
     unit_tests.scheme = { :code_coverage => true }
     unit_tests.platforms = {
       :ios => ios_deployment_target,
@@ -59,12 +57,5 @@ Build AI-powered apps and features with the Gemini API using the Firebase AI SDK
     unit_tests.source_files = [
       unit_tests_dir + '**/*.swift',
     ]
-    unit_tests.exclude_files = [
-      unit_tests_dir + 'Snippets/**/*.swift',
-    ]
-    unit_tests.resources = [
-      unit_tests_dir + 'vertexai-sdk-test-data/mock-responses',
-      unit_tests_dir + 'Resources/**/*',
-    ]
   end
 end

+ 2 - 2
FirebaseAI/Tests/TestApp/Tests/Integration/CountTokensIntegrationTests.swift

@@ -12,14 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import FirebaseAI
+import FirebaseAILogic
 import FirebaseAITestApp
 import FirebaseAuth
 import FirebaseCore
 import FirebaseStorage
 import Testing
 
-@testable import struct FirebaseAI.APIConfig
+@testable import struct FirebaseAILogic.APIConfig
 
 @Suite(.serialized)
 struct CountTokensIntegrationTests {

+ 2 - 2
FirebaseAI/Tests/TestApp/Tests/Integration/GenerateContentIntegrationTests.swift

@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import FirebaseAI
+import FirebaseAILogic
 import FirebaseAITestApp
 import FirebaseAuth
 import FirebaseCore
@@ -23,7 +23,7 @@ import Testing
   import UIKit
 #endif // canImport(UIKit)
 
-@testable import struct FirebaseAI.BackendError
+@testable import struct FirebaseAILogic.BackendError
 
 @Suite(.serialized)
 struct GenerateContentIntegrationTests {

+ 2 - 2
FirebaseAI/Tests/TestApp/Tests/Integration/ImagenIntegrationTests.swift

@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import FirebaseAI
+import FirebaseAILogic
 import FirebaseAITestApp
 import FirebaseAuth
 import FirebaseCore
@@ -24,7 +24,7 @@ import Testing
 #endif // canImport(UIKit)
 
 // TODO(#14452): Remove `@testable import` when `generateImages(prompt:gcsURI:)` is public.
-@testable import class FirebaseAI.ImagenModel
+@testable import class FirebaseAILogic.ImagenModel
 
 @Suite(
   .enabled(

+ 2 - 2
FirebaseAI/Tests/TestApp/Tests/Integration/IntegrationTests.swift

@@ -12,14 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import FirebaseAI
+import FirebaseAILogic
 import FirebaseAITestApp
 import FirebaseAuth
 import FirebaseCore
 import FirebaseStorage
 import XCTest
 
-@testable import struct FirebaseAI.CountTokensRequest
+@testable import struct FirebaseAILogic.CountTokensRequest
 
 // TODO(#14405): Migrate to Swift Testing and parameterize tests.
 final class IntegrationTests: XCTestCase {

+ 2 - 2
FirebaseAI/Tests/TestApp/Tests/Integration/LiveSessionTests.swift

@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import FirebaseAI
+import FirebaseAILogic
 import FirebaseAITestApp
 import SwiftUI
 import Testing
 
-@testable import struct FirebaseAI.APIConfig
+@testable import struct FirebaseAILogic.APIConfig
 
 @Suite(.serialized)
 struct LiveSessionTests {

+ 2 - 2
FirebaseAI/Tests/TestApp/Tests/Integration/SchemaTests.swift

@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import FirebaseAI
+import FirebaseAILogic
 import FirebaseAITestApp
 import FirebaseAuth
 import FirebaseCore
@@ -23,7 +23,7 @@ import Testing
   import UIKit
 #endif // canImport(UIKit)
 
-@testable import struct FirebaseAI.BackendError
+@testable import struct FirebaseAILogic.BackendError
 
 /// Test the schema fields.
 @Suite(.serialized)

+ 2 - 2
FirebaseAI/Tests/TestApp/Tests/Utilities/InstanceConfig.swift

@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import FirebaseAI
+import FirebaseAILogic
 import FirebaseAITestApp
 import FirebaseCore
 import Testing
 
-@testable import struct FirebaseAI.APIConfig
+@testable import struct FirebaseAILogic.APIConfig
 
 struct InstanceConfig: Equatable, Encodable {
   static let vertexAI_v1beta = InstanceConfig(

+ 1 - 1
FirebaseAI/Tests/Unit/APITests.swift

@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import FirebaseAI
+import FirebaseAILogic
 import FirebaseCore
 import XCTest
 #if canImport(AppKit)

+ 1 - 1
FirebaseAI/Tests/Unit/ChatTests.swift

@@ -16,7 +16,7 @@ import FirebaseCore
 import Foundation
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 final class ChatTests: XCTestCase {

+ 1 - 1
FirebaseAI/Tests/Unit/GenerationConfigTests.swift

@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import FirebaseAI
+import FirebaseAILogic
 import Foundation
 import XCTest
 

+ 1 - 1
FirebaseAI/Tests/Unit/GenerativeModelGoogleAITests.swift

@@ -17,7 +17,7 @@ import FirebaseAuthInterop
 import FirebaseCore
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 final class GenerativeModelGoogleAITests: XCTestCase {

+ 1 - 1
FirebaseAI/Tests/Unit/GenerativeModelVertexAITests.swift

@@ -17,7 +17,7 @@ import FirebaseAuthInterop
 import FirebaseCore
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 final class GenerativeModelVertexAITests: XCTestCase {

+ 1 - 1
FirebaseAI/Tests/Unit/JSONValueTests.swift

@@ -13,7 +13,7 @@
 // limitations under the License.
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 final class JSONValueTests: XCTestCase {

+ 1 - 1
FirebaseAI/Tests/Unit/PartTests.swift

@@ -15,7 +15,7 @@
 import Foundation
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 final class PartTests: XCTestCase {

+ 1 - 1
FirebaseAI/Tests/Unit/PartsRepresentableTests.swift

@@ -23,7 +23,7 @@ import XCTest
   import CoreImage
 #endif // canImport(CoreImage)
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 final class PartsRepresentableTests: XCTestCase {

+ 1 - 1
FirebaseAI/Tests/Unit/RequestOptionsTest.swift

@@ -14,7 +14,7 @@
 
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 final class RequestOptionsTests: XCTestCase {

+ 1 - 1
FirebaseAI/Tests/Unit/SafetyTests.swift

@@ -14,7 +14,7 @@
 
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 final class SafetyTests: XCTestCase {

+ 1 - 1
FirebaseAI/Tests/Unit/Snippets/ChatSnippets.swift

@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import FirebaseAI
+import FirebaseAILogic
 import FirebaseCore
 import XCTest
 

+ 1 - 1
FirebaseAI/Tests/Unit/Snippets/CloudStorageSnippets.swift

@@ -14,7 +14,7 @@
 
 #if SWIFT_PACKAGE // The FirebaseStorage dependency has only been added in Package.swift.
 
-  import FirebaseAI
+  import FirebaseAILogic
   import FirebaseCore
   import FirebaseStorage
 

+ 1 - 1
FirebaseAI/Tests/Unit/Snippets/CountTokensSnippets.swift

@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import FirebaseAI
+import FirebaseAILogic
 import FirebaseCore
 import XCTest
 

+ 1 - 1
FirebaseAI/Tests/Unit/Snippets/FunctionCallingSnippets.swift

@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import FirebaseAI
+import FirebaseAILogic
 import FirebaseCore
 import XCTest
 

+ 1 - 1
FirebaseAI/Tests/Unit/Snippets/LiveSnippets.swift

@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import FirebaseAI
+import FirebaseAILogic
 import FirebaseCore
 import XCTest
 

+ 1 - 1
FirebaseAI/Tests/Unit/Snippets/MultimodalSnippets.swift

@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import FirebaseAI
+import FirebaseAILogic
 import FirebaseCore
 import XCTest
 

+ 1 - 1
FirebaseAI/Tests/Unit/Snippets/StructuredOutputSnippets.swift

@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import FirebaseAI
+import FirebaseAILogic
 import FirebaseCore
 import XCTest
 

+ 1 - 1
FirebaseAI/Tests/Unit/Snippets/TextSnippets.swift

@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import FirebaseAI
+import FirebaseAILogic
 import FirebaseCore
 import XCTest
 

+ 1 - 1
FirebaseAI/Tests/Unit/TestUtilities/FirebaseAI+DefaultAPIConfig.swift

@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 extension FirebaseAI {

+ 1 - 1
FirebaseAI/Tests/Unit/TestUtilities/GenerativeModelTestUtil.swift

@@ -18,7 +18,7 @@ import FirebaseCore
 import Foundation
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 enum GenerativeModelTestUtil {

+ 1 - 1
FirebaseAI/Tests/Unit/Types/BackendTests.swift

@@ -14,7 +14,7 @@
 
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 final class BackendTests: XCTestCase {
   func testVertexAI_defaultLocation() {

+ 1 - 1
FirebaseAI/Tests/Unit/Types/CitationMetadataTests.swift

@@ -14,7 +14,7 @@
 
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 final class CitationMetadataTests: XCTestCase {

+ 1 - 1
FirebaseAI/Tests/Unit/Types/CitationTests.swift

@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import FirebaseAI
+import FirebaseAILogic
 import XCTest
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)

+ 1 - 1
FirebaseAI/Tests/Unit/Types/GenerateContentResponseTests.swift

@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 import XCTest
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)

+ 1 - 1
FirebaseAI/Tests/Unit/Types/GroundingMetadataTests.swift

@@ -14,7 +14,7 @@
 
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 final class GroundingMetadataTests: XCTestCase {

+ 1 - 1
FirebaseAI/Tests/Unit/Types/Imagen/ImageGenerationInstanceTests.swift

@@ -14,7 +14,7 @@
 
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 final class ImageGenerationInstanceTests: XCTestCase {

+ 1 - 1
FirebaseAI/Tests/Unit/Types/Imagen/ImageGenerationOutputOptionsTests.swift

@@ -14,7 +14,7 @@
 
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 final class ImageGenerationOutputOptionsTests: XCTestCase {

+ 1 - 1
FirebaseAI/Tests/Unit/Types/Imagen/ImageGenerationParametersTests.swift

@@ -14,7 +14,7 @@
 
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 final class ImageGenerationParametersTests: XCTestCase {

+ 1 - 1
FirebaseAI/Tests/Unit/Types/Imagen/ImagenGCSImageTests.swift

@@ -14,7 +14,7 @@
 
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 final class ImagenGCSImageTests: XCTestCase {

+ 1 - 1
FirebaseAI/Tests/Unit/Types/Imagen/ImagenGenerationRequestTests.swift

@@ -14,7 +14,7 @@
 
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 final class ImagenGenerationRequestTests: XCTestCase {

+ 1 - 1
FirebaseAI/Tests/Unit/Types/Imagen/ImagenGenerationResponseTests.swift

@@ -14,7 +14,7 @@
 
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 final class ImagenGenerationResponseTests: XCTestCase {

+ 1 - 1
FirebaseAI/Tests/Unit/Types/Imagen/ImagenInlineImageTests.swift

@@ -14,7 +14,7 @@
 
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 final class ImagenInlineImageTests: XCTestCase {

+ 1 - 1
FirebaseAI/Tests/Unit/Types/Imagen/RAIFilteredReasonTests.swift

@@ -14,7 +14,7 @@
 
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 final class RAIFilteredReasonTests: XCTestCase {

+ 1 - 1
FirebaseAI/Tests/Unit/Types/Internal/APIConfigTests.swift

@@ -14,7 +14,7 @@
 
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 final class APIConfigTests: XCTestCase {

+ 1 - 1
FirebaseAI/Tests/Unit/Types/Internal/Requests/CountTokensRequestTests.swift

@@ -15,7 +15,7 @@
 import Foundation
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 final class CountTokensRequestTests: XCTestCase {

+ 1 - 1
FirebaseAI/Tests/Unit/Types/InternalPartTests.swift

@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 import XCTest
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)

+ 1 - 1
FirebaseAI/Tests/Unit/Types/ModalityTokenCountTests.swift

@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import FirebaseAI
+import FirebaseAILogic
 import XCTest
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)

+ 1 - 1
FirebaseAI/Tests/Unit/Types/ProtoDateTests.swift

@@ -14,7 +14,7 @@
 
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 final class ProtoDateTests: XCTestCase {
   let decoder = JSONDecoder()

+ 1 - 1
FirebaseAI/Tests/Unit/Types/ProtoDurationTests.swift

@@ -14,7 +14,7 @@
 
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 final class ProtoDurationTests: XCTestCase {
   let decoder = JSONDecoder()

+ 1 - 1
FirebaseAI/Tests/Unit/Types/SchemaTests.swift

@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import FirebaseAI
+import FirebaseAILogic
 import Foundation
 import XCTest
 

+ 1 - 1
FirebaseAI/Tests/Unit/Types/ToolTests.swift

@@ -14,7 +14,7 @@
 
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 final class ToolTests: XCTestCase {

+ 1 - 1
FirebaseAI/Tests/Unit/VertexComponentTests.swift

@@ -17,7 +17,7 @@ internal import FirebaseCoreExtension
 import Foundation
 import XCTest
 
-@testable import FirebaseAI
+@testable import FirebaseAILogic
 
 @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
 class VertexComponentTests: XCTestCase {

+ 15 - 0
FirebaseAI/Wrapper/Sources/FirebaseAIWrapper.swift

@@ -0,0 +1,15 @@
+// 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.
+
+@_exported import FirebaseAILogic

+ 186 - 0
FirebaseAI/Wrapper/Tests/APITests.swift

@@ -0,0 +1,186 @@
+// Copyright 2023 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 FirebaseAI
+import FirebaseCore
+import XCTest
+#if canImport(AppKit)
+  import AppKit // For NSImage extensions.
+#elseif canImport(UIKit)
+  import UIKit // For UIImage extensions.
+#endif
+
+@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
+final class APITests: XCTestCase {
+  func codeSamples() async throws {
+    let app = FirebaseApp.app()
+    let config = GenerationConfig(temperature: 0.2,
+                                  topP: 0.1,
+                                  topK: 16,
+                                  candidateCount: 4,
+                                  maxOutputTokens: 256,
+                                  stopSequences: ["..."],
+                                  responseMIMEType: "text/plain")
+    let filters = [SafetySetting(harmCategory: .dangerousContent, threshold: .blockOnlyHigh)]
+    let systemInstruction = ModelContent(
+      role: "system",
+      parts: TextPart("Talk like a pirate.")
+    )
+
+    let requestOptions = RequestOptions()
+    let _ = RequestOptions(timeout: 30.0)
+
+    // Instantiate Firebase AI SDK - Default App
+    let firebaseAI = FirebaseAI.firebaseAI()
+    let _ = FirebaseAI.firebaseAI(backend: .googleAI())
+    let _ = FirebaseAI.firebaseAI(backend: .vertexAI())
+    let _ = FirebaseAI.firebaseAI(backend: .vertexAI(location: "my-location"))
+
+    // Instantiate Firebase AI SDK - Custom App
+    let _ = FirebaseAI.firebaseAI(app: app!)
+    let _ = FirebaseAI.firebaseAI(app: app!, backend: .googleAI())
+    let _ = FirebaseAI.firebaseAI(app: app!, backend: .vertexAI())
+    let _ = FirebaseAI.firebaseAI(app: app!, backend: .vertexAI(location: "my-location"))
+
+    // Permutations without optional arguments.
+
+    let _ = firebaseAI.generativeModel(modelName: "gemini-2.0-flash")
+
+    let _ = firebaseAI.generativeModel(
+      modelName: "gemini-2.0-flash",
+      safetySettings: filters
+    )
+
+    let _ = firebaseAI.generativeModel(
+      modelName: "gemini-2.0-flash",
+      generationConfig: config
+    )
+
+    let _ = firebaseAI.generativeModel(
+      modelName: "gemini-2.0-flash",
+      systemInstruction: systemInstruction
+    )
+
+    // All arguments passed.
+    let model = firebaseAI.generativeModel(
+      modelName: "gemini-2.0-flash",
+      generationConfig: config, // Optional
+      safetySettings: filters, // Optional
+      systemInstruction: systemInstruction, // Optional
+      requestOptions: requestOptions // Optional
+    )
+
+    // Full Typed Usage
+    let pngData = Data() // ....
+    let contents = [ModelContent(
+      role: "user",
+      parts: [
+        TextPart("Is it a cat?"),
+        InlineDataPart(data: pngData, mimeType: "image/png"),
+      ]
+    )]
+
+    do {
+      let response = try await model.generateContent(contents)
+      print(response.text ?? "Couldn't get text... check status")
+    } catch {
+      print("Error generating content: \(error)")
+    }
+
+    // Content input combinations.
+    let _ = try await model.generateContent("Constant String")
+    let str = "String Variable"
+    let _ = try await model.generateContent(str)
+    let _ = try await model.generateContent([str])
+    let _ = try await model.generateContent(str, "abc", "def")
+    let _ = try await model.generateContent(
+      str,
+      FileDataPart(uri: "gs://test-bucket/image.jpg", mimeType: "image/jpeg")
+    )
+    #if canImport(UIKit)
+      _ = try await model.generateContent(UIImage())
+      _ = try await model.generateContent([UIImage()])
+      _ = try await model.generateContent([str, UIImage(), TextPart(str)])
+      _ = try await model.generateContent(str, UIImage(), "def", UIImage())
+      _ = try await model.generateContent([str, UIImage(), "def", UIImage()])
+      _ = try await model.generateContent([ModelContent(parts: "def", UIImage()),
+                                           ModelContent(parts: "def", UIImage())])
+    #elseif canImport(AppKit)
+      _ = try await model.generateContent(NSImage())
+      _ = try await model.generateContent([NSImage()])
+      _ = try await model.generateContent(str, NSImage(), "def", NSImage())
+      _ = try await model.generateContent([str, NSImage(), "def", NSImage()])
+    #endif
+
+    // PartsRepresentable combinations.
+    let _ = ModelContent(parts: [TextPart(str)])
+    let _ = ModelContent(role: "model", parts: [TextPart(str)])
+    let _ = ModelContent(parts: "Constant String")
+    let _ = ModelContent(parts: str)
+    let _ = ModelContent(parts: [str])
+    let _ = ModelContent(parts: [str, InlineDataPart(data: Data(), mimeType: "foo")])
+    #if canImport(UIKit)
+      _ = ModelContent(role: "user", parts: UIImage())
+      _ = ModelContent(role: "user", parts: [UIImage()])
+      _ = ModelContent(parts: [str, UIImage()])
+      // Note: without explicitly specifying`: [any PartsRepresentable]` this will fail to compile
+      // below with "Cannot convert value of type `[Any]` to expected type `[any Part]`.
+      let representable2: [any PartsRepresentable] = [str, UIImage()]
+      _ = ModelContent(parts: representable2)
+      _ = ModelContent(parts: [str, UIImage(), TextPart(str)])
+    #elseif canImport(AppKit)
+      _ = ModelContent(role: "user", parts: NSImage())
+      _ = ModelContent(role: "user", parts: [NSImage()])
+      _ = ModelContent(parts: [str, NSImage()])
+      // Note: without explicitly specifying`: [any PartsRepresentable]` this will fail to compile
+      // below with "Cannot convert value of type `[Any]` to expected type `[any Part]`.
+      let representable2: [any PartsRepresentable] = [str, NSImage()]
+      _ = ModelContent(parts: representable2)
+      _ = ModelContent(parts: [str, NSImage(), TextPart(str)])
+    #endif
+
+    // countTokens API
+    let _: CountTokensResponse = try await model.countTokens("What color is the Sky?")
+    #if canImport(UIKit)
+      let _: CountTokensResponse = try await model.countTokens("What color is the Sky?",
+                                                               UIImage())
+      let _: CountTokensResponse = try await model.countTokens([
+        ModelContent(parts: "What color is the Sky?", UIImage()),
+        ModelContent(parts: UIImage(), "What color is the Sky?", UIImage()),
+      ])
+    #endif
+
+    // Chat
+    _ = model.startChat()
+    _ = model.startChat(history: [ModelContent(parts: "abc")])
+  }
+
+  // Public API tests for GenerateContentResponse.
+  func generateContentResponseAPI() {
+    let response = GenerateContentResponse(candidates: [])
+
+    let _: [Candidate] = response.candidates
+    let _: PromptFeedback? = response.promptFeedback
+
+    // Usage Metadata
+    guard let usageMetadata = response.usageMetadata else { fatalError() }
+    let _: Int = usageMetadata.promptTokenCount
+    let _: Int = usageMetadata.candidatesTokenCount
+    let _: Int = usageMetadata.totalTokenCount
+
+    // Computed Properties
+    let _: String? = response.text
+    let _: [FunctionCallPart] = response.functionCalls
+  }
+}

+ 70 - 0
FirebaseAILogic.podspec

@@ -0,0 +1,70 @@
+Pod::Spec.new do |s|
+  s.name             = 'FirebaseAILogic'
+  s.version          = '12.5.0'
+  s.summary          = 'Firebase AI Logic SDK'
+
+  s.description      = <<-DESC
+Build AI-powered apps and features with the Gemini API using the Firebase AI Logic SDK.
+                       DESC
+
+  s.homepage         = 'https://firebase.google.com'
+  s.license          = { :type => 'Apache-2.0', :file => 'LICENSE' }
+  s.authors          = 'Google, Inc.'
+
+  s.source           = {
+    :git => 'https://github.com/firebase/firebase-ios-sdk.git',
+    :tag => 'CocoaPods-' + s.version.to_s
+  }
+
+  s.social_media_url = 'https://twitter.com/Firebase'
+
+  ios_deployment_target = '15.0'
+  osx_deployment_target = '12.0'
+  tvos_deployment_target = '15.0'
+  watchos_deployment_target = '8.0'
+
+  s.ios.deployment_target = ios_deployment_target
+  s.osx.deployment_target = osx_deployment_target
+  s.tvos.deployment_target = tvos_deployment_target
+  s.watchos.deployment_target = watchos_deployment_target
+
+  s.cocoapods_version = '>= 1.12.0'
+  s.prefix_header_file = false
+
+  s.source_files = [
+    'FirebaseAI/Sources/**/*.swift',
+  ]
+
+  s.swift_version = '5.9'
+
+  s.framework = 'Foundation'
+  s.ios.framework = 'UIKit'
+  s.osx.framework = 'AppKit'
+  s.tvos.framework = 'UIKit'
+  s.watchos.framework = 'WatchKit'
+
+  s.dependency 'FirebaseAppCheckInterop', '~> 12.5.0'
+  s.dependency 'FirebaseAuthInterop', '~> 12.5.0'
+  s.dependency 'FirebaseCore', '~> 12.5.0'
+  s.dependency 'FirebaseCoreExtension', '~> 12.5.0'
+
+  s.test_spec 'unit' do |unit_tests|
+    unit_tests_dir = 'FirebaseAI/Tests/Unit/'
+    unit_tests.scheme = { :code_coverage => true }
+    unit_tests.platforms = {
+      :ios => ios_deployment_target,
+      :osx => osx_deployment_target,
+      :tvos => tvos_deployment_target
+    }
+    unit_tests.source_files = [
+      unit_tests_dir + '**/*.swift',
+    ]
+    unit_tests.exclude_files = [
+      unit_tests_dir + 'Snippets/**/*.swift',
+    ]
+    unit_tests.resources = [
+      unit_tests_dir + 'vertexai-sdk-test-data/mock-responses',
+      unit_tests_dir + 'Resources/**/*',
+    ]
+  end
+end

+ 23 - 4
Package.swift

@@ -26,7 +26,16 @@ let package = Package(
   products: [
     .library(
       name: "FirebaseAI",
-      targets: ["FirebaseAI"]
+      targets: [
+        "FirebaseAI",
+        "FirebaseAILogic",
+      ]
+    ),
+    .library(
+      name: "FirebaseAILogic",
+      targets: [
+        "FirebaseAILogic",
+      ]
     ),
     .library(
       name: "FirebaseAnalytics",
@@ -178,7 +187,7 @@ let package = Package(
     // MARK: - Firebase AI
 
     .target(
-      name: "FirebaseAI",
+      name: "FirebaseAILogic",
       dependencies: [
         "FirebaseAppCheckInterop",
         "FirebaseAuthInterop",
@@ -188,9 +197,9 @@ let package = Package(
       path: "FirebaseAI/Sources"
     ),
     .testTarget(
-      name: "FirebaseAIUnit",
+      name: "FirebaseAILogicUnit",
       dependencies: [
-        "FirebaseAI",
+        "FirebaseAILogic",
         "FirebaseStorage",
       ],
       path: "FirebaseAI/Tests/Unit",
@@ -202,6 +211,16 @@ let package = Package(
         .headerSearchPath("../../../"),
       ]
     ),
+    .target(
+      name: "FirebaseAI",
+      dependencies: ["FirebaseAILogic"],
+      path: "FirebaseAI/Wrapper/Sources"
+    ),
+    .testTarget(
+      name: "FirebaseAIUnit",
+      dependencies: ["FirebaseAI"],
+      path: "FirebaseAI/Wrapper/Tests"
+    ),
 
     // MARK: - Firebase Core
 

+ 1 - 0
ReleaseTooling/CarthageJSON/FirebaseAILogicBinary.json

@@ -0,0 +1 @@
+{}

+ 2 - 1
ReleaseTooling/Sources/FirebaseManifest/FirebaseManifest.swift

@@ -38,7 +38,8 @@ public let shared = Manifest(
     Pod("FirebaseABTesting", zip: true),
     Pod("FirebaseAppCheck", zip: true),
     Pod("FirebaseRemoteConfig", zip: true),
-    Pod("FirebaseAI", zip: true),
+    Pod("FirebaseAILogic", zip: true),
+    Pod("FirebaseAI", zip: false),
     Pod("FirebaseAppDistribution", isBeta: true, platforms: ["ios"], zip: true),
     Pod("FirebaseAuth", zip: true),
     Pod("FirebaseCrashlytics", zip: true),

+ 77 - 0
scripts/spm_test_schemes/FirebaseAILogicUnit.xcscheme

@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "1200"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "NO"
+            buildForArchiving = "NO"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "FirebaseAILogicUnit"
+               BuildableName = "FirebaseAILogicUnit"
+               BlueprintName = "FirebaseAILogicUnit"
+               ReferencedContainer = "container:">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES">
+      <Testables>
+         <TestableReference
+            skipped = "NO">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "FirebaseAILogicUnit"
+               BuildableName = "FirebaseAILogicUnit"
+               BlueprintName = "FirebaseAILogicUnit"
+               ReferencedContainer = "container:">
+            </BuildableReference>
+         </TestableReference>
+      </Testables>
+   </TestAction>
+   <LaunchAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      debugServiceExtension = "internal"
+      allowLocationSimulation = "YES">
+   </LaunchAction>
+   <ProfileAction
+      buildConfiguration = "Release"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      debugDocumentVersioning = "YES">
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "FirebaseAILogicUnit"
+            BuildableName = "FirebaseAILogicUnit"
+            BlueprintName = "FirebaseAILogicUnit"
+            ReferencedContainer = "container:">
+         </BuildableReference>
+      </MacroExpansion>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>

+ 1 - 1
scripts/zip_quickstart_test.sh

@@ -46,7 +46,7 @@ fi
 xcodebuild \
 -project ${SAMPLE}Example.xcodeproj \
 -scheme  ${SAMPLE}Example${SWIFT_SUFFIX} \
--destination "platform=iOS Simulator,name=$device_name" "SWIFT_VERSION=5.3" "OTHER_LDFLAGS=\$(OTHER_LDFLAGS) -ObjC" "FRAMEWORK_SEARCH_PATHS= \$(PROJECT_DIR)/Firebase/" HEADER_SEARCH_PATHS='$(PROJECT_DIR)/Firebase' \
+-destination "platform=iOS Simulator,name=$device_name" "SWIFT_VERSION=5.3" "OTHER_LDFLAGS=\$(OTHER_LDFLAGS) -ObjC" "FRAMEWORK_SEARCH_PATHS= \$(PROJECT_DIR)/Firebase/" HEADER_SEARCH_PATHS='$(inherited) $(PROJECT_DIR)/Firebase' \
 build \
 ) || EXIT_STATUS=$?