diff --git a/.github/actions/notices_generation/Gemfile.lock b/.github/actions/notices_generation/Gemfile.lock index 294d40f5067..a99250bd561 100644 --- a/.github/actions/notices_generation/Gemfile.lock +++ b/.github/actions/notices_generation/Gemfile.lock @@ -10,28 +10,85 @@ GEM tzinfo (~> 2.0) addressable (2.8.0) public_suffix (>= 2.0.2, < 5.0) + algoliasearch (1.27.5) + httpclient (~> 2.8, >= 2.8.3) + json (>= 1.5.1) atomos (0.1.3) claide (1.1.0) + cocoapods (1.12.1) + addressable (~> 2.8) + claide (>= 1.0.2, < 2.0) + cocoapods-core (= 1.12.1) + cocoapods-deintegrate (>= 1.0.3, < 2.0) + cocoapods-downloader (>= 1.6.0, < 2.0) + cocoapods-plugins (>= 1.0.0, < 2.0) + cocoapods-search (>= 1.0.0, < 2.0) + cocoapods-trunk (>= 1.6.0, < 2.0) + cocoapods-try (>= 1.1.0, < 2.0) + colored2 (~> 3.1) + escape (~> 0.0.4) + fourflusher (>= 2.3.0, < 3.0) + gh_inspector (~> 1.0) + molinillo (~> 0.8.0) + nap (~> 1.0) + ruby-macho (>= 2.3.0, < 3.0) + xcodeproj (>= 1.21.0, < 2.0) + cocoapods-core (1.12.1) + activesupport (>= 5.0, < 8) + addressable (~> 2.8) + algoliasearch (~> 1.0) + concurrent-ruby (~> 1.1) + fuzzy_match (~> 2.0.4) + nap (~> 1.0) + netrc (~> 0.11) + public_suffix (~> 4.0) + typhoeus (~> 1.0) + cocoapods-deintegrate (1.0.5) + cocoapods-downloader (1.6.3) + cocoapods-plugins (1.0.0) + nap + cocoapods-search (1.0.1) + cocoapods-trunk (1.6.0) + nap (>= 0.8, < 2.0) + netrc (~> 0.11) + cocoapods-try (1.2.0) colored2 (3.1.2) concurrent-ruby (1.2.2) + escape (0.0.4) + ethon (0.16.0) + ffi (>= 1.15.0) faraday (1.1.0) multipart-post (>= 1.2, < 3) ruby2_keywords + ffi (1.16.3) + fourflusher (2.3.1) + fuzzy_match (2.0.4) + gh_inspector (1.1.3) + httpclient (2.8.3) i18n (1.14.1) concurrent-ruby (~> 1.0) + json (2.7.2) minitest (5.20.0) + molinillo (0.8.0) multipart-post (2.1.1) nanaimo (0.3.0) + nap (1.1.0) + netrc (0.11.0) octokit (4.19.0) faraday (>= 0.9) sawyer (~> 0.8.0, >= 0.5.3) plist (3.6.0) public_suffix (4.0.6) - rexml (3.2.5) + rexml (3.2.8) + strscan (>= 3.0.9) + ruby-macho (2.5.1) ruby2_keywords (0.0.2) sawyer (0.8.2) addressable (>= 2.3.5) faraday (> 0.8, < 2.0) + strscan (3.1.0) + typhoeus (1.4.1) + ethon (>= 0.9.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) xcodeproj (1.21.0) @@ -43,10 +100,11 @@ GEM rexml (~> 3.2.4) PLATFORMS - ruby + x86_64-linux DEPENDENCIES activesupport (= 7.0.8) + cocoapods octokit (~> 4.19) plist xcodeproj (~> 1.21) diff --git a/.github/workflows/analytics.yml b/.github/workflows/analytics.yml index 0c6c12f98c0..90ef6121902 100644 --- a/.github/workflows/analytics.yml +++ b/.github/workflows/analytics.yml @@ -42,8 +42,6 @@ jobs: run: scripts/third_party/travis/retry.sh pod spec lint GoogleAppMeasurement.podspec --platforms=${{ matrix.target }} --sources=https://github.com/firebase/SpecsDev.git,https://github.com/firebase/SpecsStaging.git,https://cdn.cocoapods.org/ - name: FirebaseAnalytics run: scripts/third_party/travis/retry.sh pod spec lint FirebaseAnalytics.podspec --platforms=${{ matrix.target }} --sources=https://github.com/firebase/SpecsDev.git,https://github.com/firebase/SpecsStaging.git,https://cdn.cocoapods.org/ - - name: FirebaseAnalyticsSwift - run: scripts/third_party/travis/retry.sh scripts/pod_lib_lint.rb FirebaseAnalyticsSwift.podspec --allow-warnings --platforms=${{ matrix.target }} # The following steps are only run on `ios` due to product availability. - name: GoogleAppMeasurementOnDeviceConversion run: scripts/third_party/travis/retry.sh pod spec lint GoogleAppMeasurementOnDeviceConversion.podspec --platforms=ios --sources=https://github.com/firebase/SpecsDev.git,https://github.com/firebase/SpecsStaging.git,https://cdn.cocoapods.org/ diff --git a/.github/workflows/crashlytics.yml b/.github/workflows/crashlytics.yml index 39fb5aee43a..a0e308d1941 100644 --- a/.github/workflows/crashlytics.yml +++ b/.github/workflows/crashlytics.yml @@ -102,7 +102,7 @@ jobs: - uses: nick-fields/retry@v3 with: timeout_minutes: 120 - max_attempts: 3 + max_attempts: 5 retry_on: error retry_wait_seconds: 120 command: scripts/test_catalyst.sh FirebaseCrashlytics test FirebaseCrashlytics-Unit-unit @@ -198,5 +198,10 @@ jobs: - uses: ruby/setup-ruby@v1 - name: Setup Bundler run: scripts/setup_bundler.sh - - name: PodLibLint Auth Cron - run: scripts/third_party/travis/retry.sh scripts/pod_lib_lint.rb FirebaseCrashlytics.podspec --platforms=${{ matrix.target }} ${{ matrix.flags }} + - uses: nick-fields/retry@v3 + with: + timeout_minutes: 120 + max_attempts: 3 + retry_on: error + retry_wait_seconds: 120 + command: scripts/third_party/travis/retry.sh scripts/pod_lib_lint.rb FirebaseCrashlytics.podspec --platforms=${{ matrix.target }} ${{ matrix.flags }} diff --git a/.github/workflows/database.yml b/.github/workflows/database.yml index 309c80ffbc0..698f52ea6b4 100644 --- a/.github/workflows/database.yml +++ b/.github/workflows/database.yml @@ -135,7 +135,7 @@ jobs: runs-on: macos-14 strategy: matrix: - podspec: [FirebaseDatabase.podspec, FirebaseDatabaseSwift.podspec --allow-warnings] + podspec: [FirebaseDatabase.podspec] target: [ios, tvos, macos] flags: [ '--skip-tests --use-static-frameworks' diff --git a/.github/workflows/dynamiclinks.yml b/.github/workflows/dynamiclinks.yml index a04cefe68b1..f2679cc3fda 100644 --- a/.github/workflows/dynamiclinks.yml +++ b/.github/workflows/dynamiclinks.yml @@ -37,7 +37,7 @@ jobs: - name: Xcode run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer - name: FirebaseDynamicLinks - run: scripts/third_party/travis/retry.sh scripts/pod_lib_lint.rb FirebaseDynamicLinks.podspec + run: scripts/third_party/travis/retry.sh scripts/pod_lib_lint.rb FirebaseDynamicLinks.podspec --allow-warnings spm: # Don't run on private repo unless it is a PR. @@ -80,7 +80,7 @@ jobs: - name: Setup Bundler run: scripts/setup_bundler.sh - name: PodLibLint Storage Cron - run: scripts/third_party/travis/retry.sh scripts/pod_lib_lint.rb FirebaseDynamicLinks.podspec --platforms=ios ${{ matrix.flags }} + run: scripts/third_party/travis/retry.sh scripts/pod_lib_lint.rb FirebaseDynamicLinks.podspec --platforms=ios ${{ matrix.flags }} --allow-warnings quickstart: # Don't run on private repo unless it is a PR. diff --git a/.github/workflows/firestore.yml b/.github/workflows/firestore.yml index ccf74fc36cb..a752bc57f5c 100644 --- a/.github/workflows/firestore.yml +++ b/.github/workflows/firestore.yml @@ -105,8 +105,7 @@ jobs: (github.event_name == 'pull_request' && needs.changes.outputs.changed == 'true') strategy: matrix: - # TODO(#12769): Update to macos-14 which doesn't include Python 3.7 - os: [macos-12, ubuntu-latest] + os: [macos-14, ubuntu-latest] env: MINT_PATH: ${{ github.workspace }}/mint @@ -132,7 +131,7 @@ jobs: - uses: actions/setup-python@v4 with: - python-version: '3.7' + python-version: '3.10' - name: Setup build run: scripts/install_prereqs.sh Firestore ${{ runner.os }} cmake @@ -153,8 +152,7 @@ jobs: strategy: matrix: - # TODO(#12769): Update to macos-14 which doesn't include Python 3.7 - os: [macos-12] + os: [macos-14] databaseId: [(default), test-db] env: @@ -183,7 +181,7 @@ jobs: - uses: actions/setup-python@v4 with: - python-version: '3.7' + python-version: '3.10' - name: Install Secret GoogleService-Info.plist run: scripts/decrypt_gha_secret.sh scripts/gha-encrypted/firestore.plist.gpg \ @@ -241,8 +239,7 @@ jobs: strategy: matrix: - # TODO(#12769): Update to macos-14 which doesn't include Python 3.7 - os: [macos-12] + os: [macos-14] sanitizer: [asan, tsan] runs-on: ${{ matrix.os }} @@ -263,7 +260,7 @@ jobs: - uses: actions/setup-python@v4 with: - python-version: '3.7' + python-version: '3.10' - name: Setup build run: scripts/install_prereqs.sh Firestore ${{ runner.os }} cmake @@ -362,7 +359,6 @@ jobs: podspec: [ 'FirebaseFirestoreInternal.podspec', 'FirebaseFirestore.podspec', - 'FirebaseFirestoreSwift.podspec', ] steps: @@ -391,7 +387,6 @@ jobs: podspec: [ 'FirebaseFirestoreInternal.podspec', 'FirebaseFirestore.podspec', - 'FirebaseFirestoreSwift.podspec', ] platforms: [ 'macos', diff --git a/.github/workflows/inappmessaging.yml b/.github/workflows/inappmessaging.yml index 918563e9213..efec2295431 100644 --- a/.github/workflows/inappmessaging.yml +++ b/.github/workflows/inappmessaging.yml @@ -23,7 +23,7 @@ jobs: strategy: matrix: - podspec: [FirebaseInAppMessaging.podspec, FirebaseInAppMessagingSwift.podspec --allow-warnings] + podspec: [FirebaseInAppMessaging.podspec] os: [macos-14, macos-13] include: - os: macos-14 diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index 4e5ba16eb98..ce0a4ac8790 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -79,7 +79,7 @@ jobs: env: plist_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} signin_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} - runs-on: macos-12 # TODO: the legacy ObjC quickstarts don't run with Xcode 15. + runs-on: macos-14 steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 @@ -90,8 +90,9 @@ jobs: quickstart-ios/performance/GoogleService-Info.plist "$plist_secret" - name: Test swift quickstart run: ([ -z $plist_secret ] || scripts/third_party/travis/retry.sh scripts/test_quickstart.sh Performance true swift) - - name: Test objc quickstart - run: ([ -z $plist_secret ] || scripts/third_party/travis/retry.sh scripts/test_quickstart.sh Performance true) + # TODO: The legacy ObjC quickstarts don't run with Xcode 15, re-able if we get these working. + # - name: Test objc quickstart + # run: ([ -z $plist_secret ] || scripts/third_party/travis/retry.sh scripts/test_quickstart.sh Performance true) quickstart-ftl-cron-only: if: github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule' diff --git a/.github/workflows/remoteconfig.yml b/.github/workflows/remoteconfig.yml index 9bb193a529d..9976accbb47 100644 --- a/.github/workflows/remoteconfig.yml +++ b/.github/workflows/remoteconfig.yml @@ -60,7 +60,7 @@ jobs: matrix: # TODO: macos tests are blocked by https://github.com/erikdoe/ocmock/pull/532 target: [ios, tvos, macos --skip-tests, watchos] - podspec: [FirebaseRemoteConfig.podspec, FirebaseRemoteConfigSwift.podspec --allow-warnings --skip-tests] + podspec: [FirebaseRemoteConfig.podspec] os: [macos-14, macos-13] include: - os: macos-14 diff --git a/.github/workflows/sessions.yml b/.github/workflows/sessions.yml index 1439b4f1d15..11ffd2f942d 100644 --- a/.github/workflows/sessions.yml +++ b/.github/workflows/sessions.yml @@ -41,10 +41,13 @@ jobs: run: scripts/setup_bundler.sh - name: Xcode run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer - - name: Build and test - run: | - scripts/third_party/travis/retry.sh scripts/pod_lib_lint.rb FirebaseSessions.podspec \ - --platforms=${{ matrix.target }} ${{ matrix.tests }} + - uses: nick-fields/retry@v3 + with: + timeout_minutes: 120 + max_attempts: 3 + retry_on: error + retry_wait_seconds: 120 + command: scripts/third_party/travis/retry.sh scripts/pod_lib_lint.rb FirebaseSessions.podspec --platforms=${{ matrix.target }} ${{ matrix.tests }} spm: # Don't run on private repo unless it is a PR. @@ -71,8 +74,13 @@ jobs: run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer - name: Initialize xcodebuild run: scripts/setup_spm_tests.sh - - name: Unit Tests - run: scripts/third_party/travis/retry.sh ./scripts/build.sh FirebaseSessionsUnit ${{ matrix.target }} spm + - uses: nick-fields/retry@v3 + with: + timeout_minutes: 120 + max_attempts: 3 + retry_on: error + retry_wait_seconds: 120 + command: scripts/third_party/travis/retry.sh ./scripts/build.sh FirebaseSessionsUnit ${{ matrix.target }} spm catalyst: # Don't run on private repo unless it is a PR. @@ -87,5 +95,10 @@ jobs: - uses: ruby/setup-ruby@v1 - name: Setup Bundler run: scripts/setup_bundler.sh - - name: Setup project and Build for Catalyst - run: scripts/test_catalyst.sh FirebaseSessions test FirebaseSessions-Unit-unit + - uses: nick-fields/retry@v3 + with: + timeout_minutes: 120 + max_attempts: 3 + retry_on: error + retry_wait_seconds: 120 + command: scripts/test_catalyst.sh FirebaseSessions test FirebaseSessions-Unit-unit diff --git a/.github/workflows/spm.yml b/.github/workflows/spm.yml index 2628cde075c..7a180ebb240 100644 --- a/.github/workflows/spm.yml +++ b/.github/workflows/spm.yml @@ -88,6 +88,8 @@ jobs: strategy: matrix: # Full set of Firebase-Package tests only run on iOS. Run subset on other platforms. + # visionOS isn't buildable from here (even with Firestore source) because the test + # targets need Analytics. target: [tvOS, macOS, catalyst] os: [macos-13, macos-14] include: @@ -95,9 +97,6 @@ jobs: xcode: Xcode_15.2 - os: macos-14 xcode: Xcode_15.3 - - os: macos-14 - target: visionOS - xcode: Xcode_15.3 runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/vertexai.yml b/.github/workflows/vertexai.yml new file mode 100644 index 00000000000..da827b50912 --- /dev/null +++ b/.github/workflows/vertexai.yml @@ -0,0 +1,70 @@ +name: vertexai + +on: + pull_request: + paths: + - 'FirebaseVertexAI**' + - '.github/workflows/vertexai.yml' + - 'Gemfile*' + schedule: + # Run every day at 11pm (PST) - cron uses UTC times + - cron: '0 7 * * *' + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +jobs: + spm: + strategy: + matrix: + target: [iOS, macOS, catalyst] + os: [macos-13] + include: + - os: macos-13 + xcode: Xcode_15.2 + runs-on: ${{ matrix.os }} + env: + FIREBASECI_USE_LATEST_GOOGLEAPPMEASUREMENT: 1 + steps: + - uses: actions/checkout@v4 + - name: Xcode + run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer + - name: Initialize xcodebuild + run: scripts/setup_spm_tests.sh + - uses: nick-fields/retry@v3 + with: + timeout_minutes: 120 + max_attempts: 3 + retry_on: error + retry_wait_seconds: 120 + command: scripts/build.sh FirebaseVertexAIUnit ${{ matrix.target }} spm + + sample: + strategy: + matrix: + # Test build with debug and release configs (whether or not DEBUG is set and optimization level) + build: [build] + include: + - os: macos-13 + xcode: Xcode_15.0.1 + - os: macos-14 + xcode: Xcode_15.2 + runs-on: ${{ matrix.os }} + env: + FIREBASECI_USE_LATEST_GOOGLEAPPMEASUREMENT: 1 + steps: + - uses: actions/checkout@v4 + - name: Xcode + run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer + - name: Initialize xcodebuild + run: xcodebuild -list + - name: Placeholder GoogleService-Info.plist for build testing + run: cp FirebaseCore/Tests/Unit/Resources/GoogleService-Info.plist FirebaseVertexAI/Sample/ + - uses: nick-fields/retry@v3 + with: + timeout_minutes: 120 + max_attempts: 3 + retry_on: error + retry_wait_seconds: 120 + command: scripts/build.sh VertexSample iOS diff --git a/.github/workflows/zip.yml b/.github/workflows/zip.yml index ef41e52a963..fb4d056edfe 100644 --- a/.github/workflows/zip.yml +++ b/.github/workflows/zip.yml @@ -43,7 +43,9 @@ jobs: run: | mkdir -p release_zip_dir sh -x scripts/build_zip.sh release_zip_dir \ - "${{ github.event.inputs.custom_spec_repos || 'https://github.com/firebase/SpecsStaging.git' }}" + "${{ github.event.inputs.custom_spec_repos || 'https://github.com/firebase/SpecsStaging.git' }}" \ + build-release \ + static - uses: actions/upload-artifact@v4 with: name: Firebase-release-zip-zip @@ -68,6 +70,9 @@ jobs: # Don't run on private repo. if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' needs: build + strategy: + matrix: + linking_type: [static, dynamic] runs-on: macos-14 steps: - uses: actions/checkout@v4 @@ -84,10 +89,11 @@ jobs: mkdir -p zip_output_dir sh -x scripts/build_zip.sh \ zip_output_dir "${{ github.event.inputs.custom_spec_repos || 'https://github.com/firebase/SpecsStaging.git,https://github.com/firebase/SpecsDev.git' }}" \ - build-head + build-head \ + ${{ matrix.linking_type }} - uses: actions/upload-artifact@v4 with: - name: Firebase-actions-dir + name: ${{ matrix.linking_type == 'static' && 'Firebase-actions-dir' || 'Firebase-actions-dir-dynamic' }} # Zip the entire output directory since the builder adds subdirectories we don't know the # name of. path: zip_output_dir @@ -103,6 +109,7 @@ jobs: strategy: matrix: os: [macos-13, macos-14] + artifact: [Firebase-actions-dir, Firebase-actions-dir-dynamic] include: - os: macos-13 xcode: Xcode_15.2 @@ -114,7 +121,7 @@ jobs: - name: Get framework dir uses: actions/download-artifact@v4 with: - name: Firebase-actions-dir + name: ${{ matrix.artifact }} - uses: ruby/setup-ruby@v1 - name: Setup Bundler run: ./scripts/setup_bundler.sh @@ -164,6 +171,7 @@ jobs: strategy: matrix: os: [macos-13, macos-14] + artifact: [Firebase-actions-dir, Firebase-actions-dir-dynamic] include: - os: macos-13 xcode: Xcode_15.2 @@ -175,7 +183,7 @@ jobs: - name: Get framework dir uses: actions/download-artifact@v4 with: - name: Firebase-actions-dir + name: ${{ matrix.artifact }} - uses: ruby/setup-ruby@v1 - name: Setup Bundler run: ./scripts/setup_bundler.sh @@ -217,6 +225,7 @@ jobs: strategy: matrix: os: [macos-13, macos-14] + artifact: [Firebase-actions-dir, Firebase-actions-dir-dynamic] include: - os: macos-13 xcode: Xcode_15.2 @@ -228,7 +237,7 @@ jobs: - name: Get framework dir uses: actions/download-artifact@v4 with: - name: Firebase-actions-dir + name: ${{ matrix.artifact }} - uses: ruby/setup-ruby@v1 - name: Setup Bundler run: ./scripts/setup_bundler.sh @@ -268,6 +277,7 @@ jobs: strategy: matrix: os: [macos-13, macos-14] + artifact: [Firebase-actions-dir, Firebase-actions-dir-dynamic] include: - os: macos-13 xcode: Xcode_15.2 @@ -279,7 +289,7 @@ jobs: - name: Get framework dir uses: actions/download-artifact@v4 with: - name: Firebase-actions-dir + name: ${{ matrix.artifact }} - uses: ruby/setup-ruby@v1 - name: Setup Bundler run: ./scripts/setup_bundler.sh @@ -343,16 +353,14 @@ jobs: matrix: os: [macos-13] xcode: [Xcode_15.2] - # TODO: Building FirebaseUI fails on Xcode 15 because it needs to sign the resources. - # - os: macos-13 - # xcode: Xcode_15.2 + artifact: [Firebase-actions-dir, Firebase-actions-dir-dynamic] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - name: Get framework dir uses: actions/download-artifact@v4 with: - name: Firebase-actions-dir + name: ${{ matrix.artifact }} - uses: ruby/setup-ruby@v1 - name: Setup Bundler run: ./scripts/setup_bundler.sh @@ -396,6 +404,7 @@ jobs: strategy: matrix: os: [macos-13, macos-14] + artifact: [Firebase-actions-dir, Firebase-actions-dir-dynamic] include: - os: macos-13 xcode: Xcode_15.2 @@ -407,7 +416,7 @@ jobs: - name: Get framework dir uses: actions/download-artifact@v4 with: - name: Firebase-actions-dir + name: ${{ matrix.artifact }} - uses: ruby/setup-ruby@v1 - name: Setup Bundler run: ./scripts/setup_bundler.sh @@ -444,55 +453,59 @@ jobs: name: quickstart_artifacts_dynamiclinks path: quickstart-ios/ - # quickstart_framework_firestore: - # # Don't run on private repo. - # if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' - # needs: package-head - # env: - # plist_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} - # signin_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} - # SDK: "Firestore" - # strategy: - # matrix: - # # TODO: Building FirebaseUI fails on Xcode 15 because it needs to sign the resources. - # os: [macos-13] - # xcode: [Xcode_15.2] - # runs-on: ${{ matrix.os }} - # steps: - # - uses: actions/checkout@v4 - # - name: Get framework dir - # uses: actions/download-artifact@v4 - # with: - # name: Firebase-actions-dir - # - uses: ruby/setup-ruby@v1 - # - 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}Example" NON_FIREBASE_SDKS="SDWebImage FirebaseAuthUI FirebaseEmailAuthUI" scripts/setup_quickstart_framework.sh \ - # "${HOME}"/ios_frameworks/Firebase/NonFirebaseSDKs/* \ - # "${HOME}"/ios_frameworks/Firebase/FirebaseFirestore/* \ - # "${HOME}"/ios_frameworks/Firebase/FirebaseAuth/* \ - # "${HOME}"/ios_frameworks/Firebase/FirebaseAnalytics/* - # - name: Xcode - # run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer - # - name: Install Secret GoogleService-Info.plist - # run: scripts/decrypt_gha_secret.sh scripts/gha-encrypted/qs-firestore.plist.gpg \ - # quickstart-ios/firestore/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 firestore - # - uses: actions/upload-artifact@v4 - # if: ${{ failure() }} - # with: - # name: quickstart_artifacts_firestore - # path: quickstart-ios/ + quickstart_framework_firestore: + # Don't run on private repo. + if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' + needs: package-head + env: + plist_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} + signin_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} + SDK: "Firestore" + strategy: + matrix: + os: [macos-13, macos-14] + artifact: [Firebase-actions-dir, Firebase-actions-dir-dynamic] + include: + - os: macos-13 + xcode: Xcode_15.2 + - os: macos-14 + xcode: Xcode_15.3 + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - name: Get framework dir + uses: actions/download-artifact@v4 + with: + name: ${{ matrix.artifact }} + - uses: ruby/setup-ruby@v1 + - 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}Example" NON_FIREBASE_SDKS="SDWebImage FirebaseAuthUI FirebaseEmailAuthUI" scripts/setup_quickstart_framework.sh \ + "${HOME}"/ios_frameworks/Firebase/NonFirebaseSDKs/* \ + "${HOME}"/ios_frameworks/Firebase/FirebaseFirestore/* \ + "${HOME}"/ios_frameworks/Firebase/FirebaseAuth/* \ + "${HOME}"/ios_frameworks/Firebase/FirebaseAnalytics/* + - name: Xcode + run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer + - name: Install Secret GoogleService-Info.plist + run: scripts/decrypt_gha_secret.sh scripts/gha-encrypted/qs-firestore.plist.gpg \ + quickstart-ios/firestore/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 firestore + - uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: quickstart_artifacts_firestore + path: quickstart-ios/ check_framework_firestore_symbols: # Don't run on private repo. @@ -536,6 +549,7 @@ jobs: strategy: matrix: os: [macos-13, macos-14] + artifact: [Firebase-actions-dir, Firebase-actions-dir-dynamic] include: - os: macos-13 xcode: Xcode_15.2 @@ -547,7 +561,7 @@ jobs: - name: Get framework dir uses: actions/download-artifact@v4 with: - name: Firebase-actions-dir + name: ${{ matrix.artifact }} - uses: ruby/setup-ruby@v1 - name: Setup Bundler run: ./scripts/setup_bundler.sh @@ -592,6 +606,7 @@ jobs: strategy: matrix: os: [macos-13, macos-14] + artifact: [Firebase-actions-dir, Firebase-actions-dir-dynamic] include: - os: macos-13 xcode: Xcode_15.2 @@ -603,7 +618,7 @@ jobs: - name: Get framework dir uses: actions/download-artifact@v4 with: - name: Firebase-actions-dir + name: ${{ matrix.artifact }} - uses: ruby/setup-ruby@v1 - name: Setup Bundler run: ./scripts/setup_bundler.sh @@ -647,6 +662,7 @@ jobs: strategy: matrix: os: [macos-13, macos-14] + artifact: [Firebase-actions-dir, Firebase-actions-dir-dynamic] include: - os: macos-13 xcode: Xcode_15.2 @@ -658,7 +674,7 @@ jobs: - name: Get framework dir uses: actions/download-artifact@v4 with: - name: Firebase-actions-dir + name: ${{ matrix.artifact }} - uses: ruby/setup-ruby@v1 - name: Setup Bundler run: ./scripts/setup_bundler.sh diff --git a/Crashlytics/CHANGELOG.md b/Crashlytics/CHANGELOG.md index e12b9b00dcf..6e6fbb5def5 100644 --- a/Crashlytics/CHANGELOG.md +++ b/Crashlytics/CHANGELOG.md @@ -1,3 +1,7 @@ +# 10.27.0 +- [added] Added support for catching the SIGTERM signal (#12881). +- [fixed] Fixed a hang when persisting Remote Config Rollouts to disk (#12913). + # 10.25.0 - [changed] Removed usages of user defaults API from internal Firebase Sessions dependency to eliminate required reason impact. diff --git a/Crashlytics/Crashlytics/Controllers/FIRCLSMetricKitManager.m b/Crashlytics/Crashlytics/Controllers/FIRCLSMetricKitManager.m index 0c081df9d08..40cbcedb907 100644 --- a/Crashlytics/Crashlytics/Controllers/FIRCLSMetricKitManager.m +++ b/Crashlytics/Crashlytics/Controllers/FIRCLSMetricKitManager.m @@ -438,6 +438,8 @@ - (NSString *)getSignalName:(NSNumber *)signalCode { return @"SIGSYS"; case SIGTRAP: return @"SIGTRAP"; + case SIGTERM: + return @"SIGTERM"; default: return @"UNKNOWN"; } diff --git a/Crashlytics/Crashlytics/Controllers/FIRCLSRolloutsPersistenceManager.m b/Crashlytics/Crashlytics/Controllers/FIRCLSRolloutsPersistenceManager.m index 8bb4c5cabfa..57993a965f3 100644 --- a/Crashlytics/Crashlytics/Controllers/FIRCLSRolloutsPersistenceManager.m +++ b/Crashlytics/Crashlytics/Controllers/FIRCLSRolloutsPersistenceManager.m @@ -57,11 +57,17 @@ - (void)updateRolloutsStateToPersistenceWithRollouts:(NSData *_Nonnull)rollouts NSFileHandle *rolloutsFile = [NSFileHandle fileHandleForUpdatingAtPath:rolloutsPath]; - dispatch_sync(FIRCLSGetLoggingQueue(), ^{ - [rolloutsFile seekToEndOfFile]; - [rolloutsFile writeData:rollouts]; - NSData *newLineData = [@"\n" dataUsingEncoding:NSUTF8StringEncoding]; - [rolloutsFile writeData:newLineData]; + dispatch_async(FIRCLSGetLoggingQueue(), ^{ + @try { + [rolloutsFile seekToEndOfFile]; + NSMutableData *rolloutsWithNewLineData = [rollouts mutableCopy]; + [rolloutsWithNewLineData appendData:[@"\n" dataUsingEncoding:NSUTF8StringEncoding]]; + [rolloutsFile writeData:rolloutsWithNewLineData]; + [rolloutsFile closeFile]; + } @catch (NSException *exception) { + FIRCLSDebugLog(@"Failed to write new rollouts. Exception name: %s - message: %s", + exception.name, exception.reason); + } }); } diff --git a/Crashlytics/Crashlytics/Handlers/FIRCLSMachException.c b/Crashlytics/Crashlytics/Handlers/FIRCLSMachException.c index 92bc830edae..0b71808e7c6 100644 --- a/Crashlytics/Crashlytics/Handlers/FIRCLSMachException.c +++ b/Crashlytics/Crashlytics/Handlers/FIRCLSMachException.c @@ -150,6 +150,8 @@ exception_mask_t FIRCLSMachExceptionMaskForSignal(int signal) { return EXC_MASK_CRASH; case SIGFPE: return EXC_MASK_ARITHMETIC; + case SIGTERM: + return EXC_MASK_CRASH; } return 0; diff --git a/Crashlytics/Crashlytics/Handlers/FIRCLSSignal.c b/Crashlytics/Crashlytics/Handlers/FIRCLSSignal.c index 1fcdbf22aab..0e745932034 100644 --- a/Crashlytics/Crashlytics/Handlers/FIRCLSSignal.c +++ b/Crashlytics/Crashlytics/Handlers/FIRCLSSignal.c @@ -21,8 +21,17 @@ #include #if CLS_SIGNAL_SUPPORTED -static const int FIRCLSFatalSignals[FIRCLSSignalCount] = {SIGABRT, SIGBUS, SIGFPE, SIGILL, - SIGSEGV, SIGSYS, SIGTRAP}; +static const int FIRCLSFatalSignals[FIRCLSSignalCount] = { + SIGABRT, SIGBUS, SIGFPE, SIGILL, + SIGSEGV, SIGSYS, SIGTRAP, + // SIGTERM can be caught and is usually sent by iOS and variants + // when Apple wants to try and gracefully shutdown the app + // before sending a SIGKILL (which can't be caught). + // Some areas I've seen this happen are: + // - When the OS updates an app. + // - In some circumstances for Watchdog Events. + // - Resource overuse (CPU, Disk, ...). + SIGTERM}; #if CLS_USE_SIGALTSTACK static void FIRCLSSignalInstallAltStack(FIRCLSSignalReadContext *roContext); @@ -237,6 +246,9 @@ void FIRCLSSignalNameLookup(int number, int code, const char **name, const char case SIGTRAP: *name = "SIGTRAP"; break; + case SIGTERM: + *name = "SIGTERM"; + break; default: *name = "UNKNOWN"; break; diff --git a/Crashlytics/Crashlytics/Handlers/FIRCLSSignal.h b/Crashlytics/Crashlytics/Handlers/FIRCLSSignal.h index 17d14810080..e9e0478c259 100644 --- a/Crashlytics/Crashlytics/Handlers/FIRCLSSignal.h +++ b/Crashlytics/Crashlytics/Handlers/FIRCLSSignal.h @@ -30,7 +30,8 @@ #endif #if CLS_SIGNAL_SUPPORTED -#define FIRCLSSignalCount (7) +// keep in sync with the list in _FIRCLSFatalSignals_. +#define FIRCLSSignalCount (8) typedef struct { const char* path; diff --git a/Crashlytics/UnitTests/FIRCLSRolloutsPersistenceManagerTests.m b/Crashlytics/UnitTests/FIRCLSRolloutsPersistenceManagerTests.m index aec030d7538..4caceb242b1 100644 --- a/Crashlytics/UnitTests/FIRCLSRolloutsPersistenceManagerTests.m +++ b/Crashlytics/UnitTests/FIRCLSRolloutsPersistenceManagerTests.m @@ -16,6 +16,7 @@ #import #import "Crashlytics/Crashlytics/Components/FIRCLSContext.h" +#include "Crashlytics/Crashlytics/Components/FIRCLSGlobals.h" #import "Crashlytics/Crashlytics/Controllers/FIRCLSRolloutsPersistenceManager.h" #import "Crashlytics/Crashlytics/Models/FIRCLSInternalReport.h" #import "Crashlytics/UnitTests/Mocks/FIRCLSTempMockFileManager.h" @@ -51,6 +52,9 @@ - (void)tearDown { } - (void)testUpdateRolloutsStateToPersistenceWithRollouts { + XCTestExpectation *expectation = [[XCTestExpectation alloc] + initWithDescription:@"Expect updating rollouts to finish writing."]; + NSString *encodedStateString = @"{rollouts:[{\"parameter_key\":\"6d795f66656174757265\",\"parameter_value\":" @"\"e8bf99e698af7468656d6973e79a84e6b58be8af95e695b0e68daeefbc8ce8be93e585a5e4b8ade69687\"," @@ -64,7 +68,43 @@ - (void)testUpdateRolloutsStateToPersistenceWithRollouts { [self.rolloutsPersistenceManager updateRolloutsStateToPersistenceWithRollouts:data reportID:reportId]; + + // Wait for the logging queue to finish. + dispatch_async(FIRCLSGetLoggingQueue(), ^{ + [expectation fulfill]; + }); + + [self waitForExpectations:@[ expectation ] timeout:3]; + XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:rolloutsFilePath]); } +- (void)testUpdateRolloutsStateToPersistenceEnsureNoHang { + dispatch_queue_t testQueue = dispatch_queue_create("TestQueue", DISPATCH_QUEUE_SERIAL); + XCTestExpectation *expectation = + [[XCTestExpectation alloc] initWithDescription:@"Expect updating rollouts to return."]; + NSString *encodedStateString = + @"{rollouts:[{\"parameter_key\":\"6d795f66656174757265\",\"parameter_value\":" + @"\"e8bf99e698af7468656d6973e79a84e6b58be8af95e695b0e68daeefbc8ce8be93e585a5e4b8ade69687\"," + @"\"rollout_id\":\"726f6c6c6f75745f31\",\"template_version\":1,\"variant_id\":" + @"\"636f6e74726f6c\"}]}"; + + NSData *data = [encodedStateString dataUsingEncoding:NSUTF8StringEncoding]; + + // Clog up the queue with a long running operation. This sleep time + // must be longer than the expectation timeout. + dispatch_async(FIRCLSGetLoggingQueue(), ^{ + sleep(10); + }); + + dispatch_async(testQueue, ^{ + // Ensure that calling this returns quickly so we don't hang + [self.rolloutsPersistenceManager updateRolloutsStateToPersistenceWithRollouts:data + reportID:reportId]; + [expectation fulfill]; + }); + + [self waitForExpectations:@[ expectation ] timeout:3]; +} + @end diff --git a/Dangerfile b/Dangerfile index 9579b574add..87b999c2c86 100644 --- a/Dangerfile +++ b/Dangerfile @@ -64,6 +64,7 @@ def labelsForModifiedFiles() labels.push("api: performance") if @has_performance_changes labels.push("api: remoteconfig") if @has_remoteconfig_changes labels.push("api: storage") if @has_storage_changes + labels.push("api: vertexai") if @has_vertexai_changes labels.push("release-tooling") if @has_releasetooling_changes labels.push("public-api-change") if @has_api_changes return labels @@ -100,7 +101,8 @@ has_license_changes = didModify(["LICENSE"]) "Messaging", "Performance", "RemoteConfig", - "Storage" + "Storage", + "VertexAI" ] ## Product directories @@ -149,6 +151,7 @@ has_license_changes = didModify(["LICENSE"]) @has_remoteconfig_changes = hasChangesIn("FirebaseRemoteConfig") @has_remoteconfig_api_changes = hasChangesIn("FirebaseRemoteConfig/Sources/Public/") @has_storage_changes = hasChangesIn("FirebaseStorage") +@has_vertexai_changes = hasChangesIn("FirebaseVertexAI") @has_releasetooling_changes = hasChangesIn("ReleaseTooling/") @has_public_additions = hasAdditionsIn("Public/") diff --git a/Example/tvOSSample/tvOSSample/AuthViewController.swift b/Example/tvOSSample/tvOSSample/AuthViewController.swift index 7809d2664b1..afcc7aae2cc 100644 --- a/Example/tvOSSample/tvOSSample/AuthViewController.swift +++ b/Example/tvOSSample/tvOSSample/AuthViewController.swift @@ -55,7 +55,7 @@ class AuthViewController: UIViewController { // MARK: - Internal Helpers private func setUserSignedIn(_ user: User?) { - if let user = user { + if let user { providers.isHidden = true signedIn.isHidden = false diff --git a/Example/watchOSSample/ServiceExtension/NotificationService.swift b/Example/watchOSSample/ServiceExtension/NotificationService.swift index 890c58e486d..95391b5b526 100644 --- a/Example/watchOSSample/ServiceExtension/NotificationService.swift +++ b/Example/watchOSSample/ServiceExtension/NotificationService.swift @@ -25,7 +25,7 @@ class NotificationService: UNNotificationServiceExtension { self.contentHandler = contentHandler bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) - if let bestAttemptContent = bestAttemptContent { + if let bestAttemptContent { // Modify the notification content here... bestAttemptContent.title = "\(bestAttemptContent.title) 👩‍💻" @@ -39,7 +39,7 @@ class NotificationService: UNNotificationServiceExtension { // Called just before the extension will be terminated by the system. // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the // original push payload will be used. - if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { + if let contentHandler, let bestAttemptContent { contentHandler(bestAttemptContent) } } diff --git a/Firebase.podspec b/Firebase.podspec index 18a33a78108..dfbed0c2b8d 100644 --- a/Firebase.podspec +++ b/Firebase.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'Firebase' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Firebase' s.description = <<-DESC @@ -36,14 +36,14 @@ Simplify your app development, grow your user base, and monetize more effectivel ss.ios.deployment_target = '10.0' ss.osx.deployment_target = '10.13' ss.tvos.deployment_target = '12.0' - ss.ios.dependency 'FirebaseAnalytics', '~> 10.25.0' - ss.osx.dependency 'FirebaseAnalytics', '~> 10.25.0' - ss.tvos.dependency 'FirebaseAnalytics', '~> 10.25.0' + ss.ios.dependency 'FirebaseAnalytics', '~> 10.27.0' + ss.osx.dependency 'FirebaseAnalytics', '~> 10.27.0' + ss.tvos.dependency 'FirebaseAnalytics', '~> 10.27.0' ss.dependency 'Firebase/CoreOnly' end s.subspec 'CoreOnly' do |ss| - ss.dependency 'FirebaseCore', '10.25.0' + ss.dependency 'FirebaseCore', '10.27.0' ss.source_files = 'CoreOnly/Sources/Firebase.h' ss.preserve_paths = 'CoreOnly/Sources/module.modulemap' if ENV['FIREBASE_POD_REPO_FOR_DEV_POD'] then @@ -79,13 +79,13 @@ Simplify your app development, grow your user base, and monetize more effectivel ss.ios.deployment_target = '10.0' ss.osx.deployment_target = '10.13' ss.tvos.deployment_target = '12.0' - ss.dependency 'FirebaseAnalytics/WithoutAdIdSupport', '~> 10.25.0' + ss.dependency 'FirebaseAnalytics/WithoutAdIdSupport', '~> 10.27.0' ss.dependency 'Firebase/CoreOnly' end s.subspec 'ABTesting' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseABTesting', '~> 10.25.0' + ss.dependency 'FirebaseABTesting', '~> 10.27.0' # Standard platforms PLUS watchOS. ss.ios.deployment_target = '11.0' ss.osx.deployment_target = '10.13' @@ -95,13 +95,13 @@ Simplify your app development, grow your user base, and monetize more effectivel s.subspec 'AppDistribution' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.ios.dependency 'FirebaseAppDistribution', '~> 10.25.0-beta' + ss.ios.dependency 'FirebaseAppDistribution', '~> 10.27.0-beta' ss.ios.deployment_target = '11.0' end s.subspec 'AppCheck' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseAppCheck', '~> 10.25.0' + ss.dependency 'FirebaseAppCheck', '~> 10.27.0' ss.ios.deployment_target = '11.0' ss.osx.deployment_target = '10.13' ss.tvos.deployment_target = '12.0' @@ -110,7 +110,7 @@ Simplify your app development, grow your user base, and monetize more effectivel s.subspec 'Auth' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseAuth', '~> 10.25.0' + ss.dependency 'FirebaseAuth', '~> 10.27.0' # Standard platforms PLUS watchOS. ss.ios.deployment_target = '11.0' ss.osx.deployment_target = '10.13' @@ -120,7 +120,7 @@ Simplify your app development, grow your user base, and monetize more effectivel s.subspec 'Crashlytics' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseCrashlytics', '~> 10.25.0' + ss.dependency 'FirebaseCrashlytics', '~> 10.27.0' # Standard platforms PLUS watchOS. ss.ios.deployment_target = '11.0' ss.osx.deployment_target = '10.13' @@ -130,7 +130,7 @@ Simplify your app development, grow your user base, and monetize more effectivel s.subspec 'Database' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseDatabase', '~> 10.25.0' + ss.dependency 'FirebaseDatabase', '~> 10.27.0' # Standard platforms PLUS watchOS 7. ss.ios.deployment_target = '11.0' ss.osx.deployment_target = '10.13' @@ -140,13 +140,13 @@ Simplify your app development, grow your user base, and monetize more effectivel s.subspec 'DynamicLinks' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.ios.dependency 'FirebaseDynamicLinks', '~> 10.25.0' + ss.ios.dependency 'FirebaseDynamicLinks', '~> 10.27.0' ss.ios.deployment_target = '11.0' end s.subspec 'Firestore' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseFirestore', '~> 10.25.0' + ss.dependency 'FirebaseFirestore', '~> 10.27.0' ss.ios.deployment_target = '11.0' ss.osx.deployment_target = '10.13' ss.tvos.deployment_target = '12.0' @@ -154,7 +154,7 @@ Simplify your app development, grow your user base, and monetize more effectivel s.subspec 'Functions' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseFunctions', '~> 10.25.0' + ss.dependency 'FirebaseFunctions', '~> 10.27.0' # Standard platforms PLUS watchOS. ss.ios.deployment_target = '11.0' ss.osx.deployment_target = '10.13' @@ -164,20 +164,20 @@ Simplify your app development, grow your user base, and monetize more effectivel s.subspec 'InAppMessaging' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.ios.dependency 'FirebaseInAppMessaging', '~> 10.25.0-beta' - ss.tvos.dependency 'FirebaseInAppMessaging', '~> 10.25.0-beta' + ss.ios.dependency 'FirebaseInAppMessaging', '~> 10.27.0-beta' + ss.tvos.dependency 'FirebaseInAppMessaging', '~> 10.27.0-beta' ss.ios.deployment_target = '11.0' ss.tvos.deployment_target = '12.0' end s.subspec 'Installations' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseInstallations', '~> 10.25.0' + ss.dependency 'FirebaseInstallations', '~> 10.27.0' end s.subspec 'Messaging' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseMessaging', '~> 10.25.0' + ss.dependency 'FirebaseMessaging', '~> 10.27.0' # Standard platforms PLUS watchOS. ss.ios.deployment_target = '11.0' ss.osx.deployment_target = '10.13' @@ -187,7 +187,7 @@ Simplify your app development, grow your user base, and monetize more effectivel s.subspec 'MLModelDownloader' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseMLModelDownloader', '~> 10.25.0-beta' + ss.dependency 'FirebaseMLModelDownloader', '~> 10.27.0-beta' # Standard platforms PLUS watchOS. ss.ios.deployment_target = '11.0' ss.osx.deployment_target = '10.13' @@ -197,15 +197,15 @@ Simplify your app development, grow your user base, and monetize more effectivel s.subspec 'Performance' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.ios.dependency 'FirebasePerformance', '~> 10.25.0' - ss.tvos.dependency 'FirebasePerformance', '~> 10.25.0' + ss.ios.dependency 'FirebasePerformance', '~> 10.27.0' + ss.tvos.dependency 'FirebasePerformance', '~> 10.27.0' ss.ios.deployment_target = '11.0' ss.tvos.deployment_target = '12.0' end s.subspec 'RemoteConfig' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseRemoteConfig', '~> 10.25.0' + ss.dependency 'FirebaseRemoteConfig', '~> 10.27.0' # Standard platforms PLUS watchOS. ss.ios.deployment_target = '11.0' ss.osx.deployment_target = '10.13' @@ -215,7 +215,7 @@ Simplify your app development, grow your user base, and monetize more effectivel s.subspec 'Storage' do |ss| ss.dependency 'Firebase/CoreOnly' - ss.dependency 'FirebaseStorage', '~> 10.25.0' + ss.dependency 'FirebaseStorage', '~> 10.27.0' # Standard platforms PLUS watchOS. ss.ios.deployment_target = '11.0' ss.osx.deployment_target = '10.13' diff --git a/FirebaseABTesting.podspec b/FirebaseABTesting.podspec index 15aa0f94025..46ae80fe177 100644 --- a/FirebaseABTesting.podspec +++ b/FirebaseABTesting.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseABTesting' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Firebase ABTesting' s.description = <<-DESC diff --git a/FirebaseAnalytics.podspec b/FirebaseAnalytics.podspec index ff954c0ad5b..ba565172565 100644 --- a/FirebaseAnalytics.podspec +++ b/FirebaseAnalytics.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseAnalytics' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Firebase Analytics for iOS' s.description = <<-DESC @@ -13,7 +13,7 @@ Pod::Spec.new do |s| s.authors = 'Google, Inc.' s.source = { - :http => 'https://dl.google.com/firebase/ios/analytics/4b9dbef45221ba96/FirebaseAnalytics-10.25.0.tar.gz' + :http => 'https://dl.google.com/firebase/ios/analytics/069659a8d012c35e/FirebaseAnalytics-10.27.0.tar.gz' } s.cocoapods_version = '>= 1.12.0' @@ -37,12 +37,12 @@ Pod::Spec.new do |s| s.default_subspecs = 'AdIdSupport' s.subspec 'AdIdSupport' do |ss| - ss.dependency 'GoogleAppMeasurement', '10.25.0' + ss.dependency 'GoogleAppMeasurement', '10.27.0' ss.vendored_frameworks = 'Frameworks/FirebaseAnalytics.xcframework' end s.subspec 'WithoutAdIdSupport' do |ss| - ss.dependency 'GoogleAppMeasurement/WithoutAdIdSupport', '10.25.0' + ss.dependency 'GoogleAppMeasurement/WithoutAdIdSupport', '10.27.0' ss.vendored_frameworks = 'Frameworks/FirebaseAnalytics.xcframework' end diff --git a/FirebaseAnalyticsOnDeviceConversion.podspec b/FirebaseAnalyticsOnDeviceConversion.podspec index 1ad84ef275c..03dd329904b 100644 --- a/FirebaseAnalyticsOnDeviceConversion.podspec +++ b/FirebaseAnalyticsOnDeviceConversion.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseAnalyticsOnDeviceConversion' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'On device conversion measurement plugin for FirebaseAnalytics. Not intended for direct use.' s.description = <<-DESC @@ -18,7 +18,7 @@ Pod::Spec.new do |s| s.cocoapods_version = '>= 1.12.0' - s.dependency 'GoogleAppMeasurementOnDeviceConversion', '10.25.0' + s.dependency 'GoogleAppMeasurementOnDeviceConversion', '10.27.0' s.static_framework = true diff --git a/FirebaseAnalyticsSwift/README.md b/FirebaseAnalyticsSwift/README.md index fff3f702ad9..5c605d01774 100644 --- a/FirebaseAnalyticsSwift/README.md +++ b/FirebaseAnalyticsSwift/README.md @@ -90,11 +90,11 @@ extension View { func analyticsScreen(name: String, class screenClass: String? = nil, extraParameters: [String: Any]? = nil) -> some View { onAppear { var params: [String: Any] = [AnalyticsParameterScreenName: name] - if let screenClass = screenClass { + if let screenClass { params[AnalyticsParameterScreenClass] = screenClass } - if let extraParams = extraParameters { - params.merge(extraParams) { _, new in new } + if let extraParameters { + params.merge(extraParameters) { _, new in new } } Analytics.logEvent(AnalyticsEventScreenView, parameters: params) } diff --git a/FirebaseAppCheck.podspec b/FirebaseAppCheck.podspec index 678f2823dcf..c8d439f4327 100644 --- a/FirebaseAppCheck.podspec +++ b/FirebaseAppCheck.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseAppCheck' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Firebase App Check SDK.' s.description = <<-DESC @@ -46,7 +46,7 @@ Pod::Spec.new do |s| s.dependency 'AppCheckCore', '~> 10.19' s.dependency 'FirebaseAppCheckInterop', '~> 10.17' - s.dependency 'FirebaseCore', '~> 10.0' + s.dependency 'FirebaseCore', '~> 10.18' s.dependency 'PromisesObjC', '~> 2.1' s.dependency 'GoogleUtilities/Environment', '~> 7.13' s.dependency 'GoogleUtilities/UserDefaults', '~> 7.13' diff --git a/FirebaseAppCheck/Apps/FIRAppCheckTestApp/FIRAppCheckTestApp/AppDelegate.swift b/FirebaseAppCheck/Apps/FIRAppCheckTestApp/FIRAppCheckTestApp/AppDelegate.swift index 1f36beb957d..661fd9fbf0b 100644 --- a/FirebaseAppCheck/Apps/FIRAppCheckTestApp/FIRAppCheckTestApp/AppDelegate.swift +++ b/FirebaseAppCheck/Apps/FIRAppCheckTestApp/FIRAppCheckTestApp/AppDelegate.swift @@ -72,11 +72,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } DeviceCheckProvider(app: firebaseApp)?.getToken { token, error in - if let token = token { + if let token { print("DeviceCheck token: \(token.token), expiration date: \(token.expirationDate)") } - if let error = error { + if let error { print("DeviceCheck error: \((error as NSError).userInfo)") } } @@ -91,11 +91,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate { print("Debug token: \(debugProvider.currentDebugToken())") debugProvider.getToken { token, error in - if let token = token { + if let token { print("Debug FAC token: \(token.token), expiration date: \(token.expirationDate)") } - if let error = error { + if let error { print("Debug error: \(error)") } } @@ -106,11 +106,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func requestLimitedUseToken() { AppCheck.appCheck().limitedUseToken { result, error in - if let result = result { + if let result { print("FAC limited-use token: \(result.token), expiration date: \(result.expirationDate)") } - if let error = error { + if let error { print("Error: \(String(describing: error))") } } @@ -128,11 +128,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } appAttestProvider.getToken { token, error in - if let token = token { + if let token { print("App Attest FAC token: \(token.token), expiration date: \(token.expirationDate)") } - if let error = error { + if let error { print("App Attest error: \(error)") } } diff --git a/FirebaseAppCheck/CHANGELOG.md b/FirebaseAppCheck/CHANGELOG.md index 6876bfbaf4d..84f16f1468f 100644 --- a/FirebaseAppCheck/CHANGELOG.md +++ b/FirebaseAppCheck/CHANGELOG.md @@ -1,3 +1,6 @@ +# 10.27.0 +- [fixed] [CocoaPods] missing symbol error for FIRGetLoggerLevel. (#12899) + # 10.25.0 - [changed] Removed usages of user defaults API to eliminate required reason impact. diff --git a/FirebaseAppCheck/Tests/Unit/Swift/AppCheckAPITests.swift b/FirebaseAppCheck/Tests/Unit/Swift/AppCheckAPITests.swift index 4e1894501d2..053a12156fa 100644 --- a/FirebaseAppCheck/Tests/Unit/Swift/AppCheckAPITests.swift +++ b/FirebaseAppCheck/Tests/Unit/Swift/AppCheckAPITests.swift @@ -119,7 +119,7 @@ final class AppCheckAPITests { // MARK: - AppCheckErrors AppCheck.appCheck().token(forcingRefresh: false) { _, error in - if let error = error { + if let error { switch error { case AppCheckErrorCode.unknown: break diff --git a/FirebaseAppCheckInterop.podspec b/FirebaseAppCheckInterop.podspec index ea4bf003d1b..a957d166efb 100644 --- a/FirebaseAppCheckInterop.podspec +++ b/FirebaseAppCheckInterop.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseAppCheckInterop' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Interfaces that allow other Firebase SDKs to use AppCheck functionality.' s.description = <<-DESC diff --git a/FirebaseAppDistribution.podspec b/FirebaseAppDistribution.podspec index ae79c61df45..2fad9cead8d 100644 --- a/FirebaseAppDistribution.podspec +++ b/FirebaseAppDistribution.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseAppDistribution' - s.version = '10.25.0-beta' + s.version = '10.27.0-beta' s.summary = 'App Distribution for Firebase iOS SDK.' s.description = <<-DESC diff --git a/FirebaseAuth.podspec b/FirebaseAuth.podspec index f25237ecc9c..c6446e59e82 100644 --- a/FirebaseAuth.podspec +++ b/FirebaseAuth.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseAuth' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Apple platform client for Firebase Authentication' s.description = <<-DESC diff --git a/FirebaseAuth/Tests/Sample/SwiftApiTests/AccountInfoTests.swift b/FirebaseAuth/Tests/Sample/SwiftApiTests/AccountInfoTests.swift index 882c9fb85b5..c6bcbda56c7 100644 --- a/FirebaseAuth/Tests/Sample/SwiftApiTests/AccountInfoTests.swift +++ b/FirebaseAuth/Tests/Sample/SwiftApiTests/AccountInfoTests.swift @@ -43,7 +43,7 @@ class AccountInfoTests: TestsBase { let auth = Auth.auth() let expectation1 = expectation(description: "Created account with email and password.") auth.createUser(withEmail: kOldUserEmail, password: "password") { user, error in - if let error = error { + if let error { XCTAssertEqual((error as NSError).code, AuthErrorCode.emailAlreadyInUse.rawValue, "Created a user despite it already exiting.") diff --git a/FirebaseAuth/Tests/Sample/SwiftApiTests/EmailPasswordTests.swift b/FirebaseAuth/Tests/Sample/SwiftApiTests/EmailPasswordTests.swift index 5fa78856d0f..ee34320dd9c 100644 --- a/FirebaseAuth/Tests/Sample/SwiftApiTests/EmailPasswordTests.swift +++ b/FirebaseAuth/Tests/Sample/SwiftApiTests/EmailPasswordTests.swift @@ -29,7 +29,7 @@ class EmailPasswordTests: TestsBase { let auth = Auth.auth() let expectation = self.expectation(description: "Created account with email and password.") auth.createUser(withEmail: kNewEmailToCreateUser, password: "password") { result, error in - if let error = error { + if let error { print("createUserWithEmail has error: \(error)") } expectation.fulfill() diff --git a/FirebaseAuth/Tests/Sample/SwiftApiTests/FacebookTests.swift b/FirebaseAuth/Tests/Sample/SwiftApiTests/FacebookTests.swift index f19471a4bc4..d5dd3bb6f71 100644 --- a/FirebaseAuth/Tests/Sample/SwiftApiTests/FacebookTests.swift +++ b/FirebaseAuth/Tests/Sample/SwiftApiTests/FacebookTests.swift @@ -30,7 +30,7 @@ import XCTest // let credential = FacebookAuthProvider.credential(withAccessToken: facebookAccessToken) // let expectation = self.expectation(description: "Signing in with Facebook finished.") // auth.signIn(with: credential) { result, error in -// if let error = error { +// if let error { // XCTFail("Signing in with Facebook had error: \(error)") // } else { // XCTAssertEqual(auth.currentUser?.displayName, Credentials.kFacebookUserName) @@ -69,7 +69,7 @@ import XCTest // let credential = FacebookAuthProvider.credential(withAccessToken: facebookAccessToken) // let expectation = self.expectation(description: "Facebook linking finished.") // auth.currentUser?.link(with: credential, completion: { result, error in -// if let error = error { +// if let error { // XCTFail("Link to Firebase error: \(error)") // } else { // guard let providers = (auth.currentUser?.providerData) else { @@ -124,7 +124,7 @@ import XCTest // fetcher.setRequestValue("text/plain", forHTTPHeaderField: "Content-Type") // let expectation = self.expectation(description: "Creating Facebook account finished.") // fetcher.beginFetch { data, error in -// if let error = error { +// if let error { // let error = error as NSError // if let message = String(data: error.userInfo["data"] as! Data, encoding: .utf8) { // // May get transient errors here for too many api calls when tests run frequently. @@ -181,7 +181,7 @@ import XCTest // fetcher.setRequestValue("text/plain", forHTTPHeaderField: "Content-Type") // let expectation = self.expectation(description: "Deleting Facebook account finished.") // fetcher.beginFetch { data, error in -// if let error = error { +// if let error { // XCTFail("Deleting Facebook account failed with error: \(error)") // } // expectation.fulfill() diff --git a/FirebaseAuth/Tests/Sample/SwiftApiTests/GoogleTests.swift b/FirebaseAuth/Tests/Sample/SwiftApiTests/GoogleTests.swift index 3da662b0f29..9a2925914b4 100644 --- a/FirebaseAuth/Tests/Sample/SwiftApiTests/GoogleTests.swift +++ b/FirebaseAuth/Tests/Sample/SwiftApiTests/GoogleTests.swift @@ -29,7 +29,7 @@ class GoogleTests: TestsBase { accessToken: googleAccessToken) let expectation = self.expectation(description: "Signing in with Google finished.") auth.signIn(with: credential) { result, error in - if let error = error { + if let error { print("Signing in with Google had error: \(error)") } expectation.fulfill() @@ -65,7 +65,7 @@ class GoogleTests: TestsBase { fetcher.setRequestValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") let expectation = self.expectation(description: "Exchanging Google account tokens finished.") fetcher.beginFetch { data, error in - if let error = error { + if let error { XCTFail("Exchanging Google account tokens finished with error: \(error)") } else { do { diff --git a/FirebaseAuth/Tests/Sample/SwiftApiTests/TestsBase.swift b/FirebaseAuth/Tests/Sample/SwiftApiTests/TestsBase.swift index e1f0721b82a..9440f4be640 100644 --- a/FirebaseAuth/Tests/Sample/SwiftApiTests/TestsBase.swift +++ b/FirebaseAuth/Tests/Sample/SwiftApiTests/TestsBase.swift @@ -38,7 +38,7 @@ class TestsBase: XCTestCase { let expectation = self.expectation(description: "Anonymous sign-in finished.") auth.signInAnonymously { result, error in - if let error = error { + if let error { print("Anonymous sign in error: \(error)") } expectation.fulfill() @@ -59,7 +59,7 @@ class TestsBase: XCTestCase { let auth = Auth.auth() let expectation = self.expectation(description: "Delete current user finished.") auth.currentUser?.delete { error in - if let error = error { + if let error { print("Anonymous sign in error: \(error)") } expectation.fulfill() diff --git a/FirebaseAuthInterop.podspec b/FirebaseAuthInterop.podspec index 89409aaec80..c1c6b0b2d66 100644 --- a/FirebaseAuthInterop.podspec +++ b/FirebaseAuthInterop.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseAuthInterop' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Interfaces that allow other Firebase SDKs to use Auth functionality.' s.description = <<-DESC diff --git a/FirebaseCombineSwift/DECISIONS.md b/FirebaseCombineSwift/DECISIONS.md index b8932edfcc6..8d4b642b448 100644 --- a/FirebaseCombineSwift/DECISIONS.md +++ b/FirebaseCombineSwift/DECISIONS.md @@ -28,9 +28,9 @@ extension Auth { password: String) -> Future { Future { /* [weak self] <-- not required */ promise in self?.createUser(withEmail: email, password: password) { authDataResult, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let authDataResult = authDataResult { + } else if let authDataResult { promise(.success(authDataResult)) } } @@ -59,4 +59,4 @@ Using the same method and parameter names for one-shot asynchronous methods resu ![image](https://user-images.githubusercontent.com/232107/99672274-76f05680-2a73-11eb-880a-3563f293de7d.png) -To achieve the same for methods that return a stream of events, we'd have to name those `addXzyListener`. This would be in contrast to Apple's naming scheme (e.g. `dataTask(with:completionHandler)` -> `dataTaskPublisher(for:)` \ No newline at end of file +To achieve the same for methods that return a stream of events, we'd have to name those `addXzyListener`. This would be in contrast to Apple's naming scheme (e.g. `dataTask(with:completionHandler)` -> `dataTaskPublisher(for:)` diff --git a/FirebaseCombineSwift/README.md b/FirebaseCombineSwift/README.md index 88038441c28..bd98eb35d81 100644 --- a/FirebaseCombineSwift/README.md +++ b/FirebaseCombineSwift/README.md @@ -78,7 +78,7 @@ In the `sign(_:didSignInFor:withError:)` method, get a Google ID token and Googl ```swift func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error?) { // ... - if let error = error { + if let error { // ... return } diff --git a/FirebaseCombineSwift/Sources/Auth/Auth+Combine.swift b/FirebaseCombineSwift/Sources/Auth/Auth+Combine.swift index a146fd26b4e..288d1a0490b 100644 --- a/FirebaseCombineSwift/Sources/Auth/Auth+Combine.swift +++ b/FirebaseCombineSwift/Sources/Auth/Auth+Combine.swift @@ -86,7 +86,7 @@ public extension Auth { func updateCurrentUser(_ user: User) -> Future { Future { promise in self.updateCurrentUser(user) { error in - if let error = error { + if let error { promise(.failure(error)) } else { promise(.success(())) @@ -117,9 +117,9 @@ public extension Auth { func signInAnonymously() -> Future { Future { promise in self.signInAnonymously { authDataResult, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let authDataResult = authDataResult { + } else if let authDataResult { promise(.success(authDataResult)) } } @@ -155,9 +155,9 @@ public extension Auth { password: String) -> Future { Future { promise in self.createUser(withEmail: email, password: password) { authDataResult, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let authDataResult = authDataResult { + } else if let authDataResult { promise(.success(authDataResult)) } } @@ -189,9 +189,9 @@ public extension Auth { password: String) -> Future { Future { promise in self.signIn(withEmail: email, password: password) { authDataResult, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let authDataResult = authDataResult { + } else if let authDataResult { promise(.success(authDataResult)) } } @@ -224,9 +224,9 @@ public extension Auth { link: String) -> Future { Future { promise in self.signIn(withEmail: email, link: link) { authDataResult, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let authDataResult = authDataResult { + } else if let authDataResult { promise(.success(authDataResult)) } } @@ -249,7 +249,7 @@ public extension Auth { actionCodeSettings: ActionCodeSettings) -> Future { Future { promise in self.sendSignInLink(toEmail: email, actionCodeSettings: actionCodeSettings) { error in - if let error = error { + if let error { promise(.failure(error)) } else { promise(.success(())) @@ -274,9 +274,9 @@ public extension Auth { func fetchSignInMethods(forEmail email: String) -> Future<[String], Error> { Future<[String], Error> { promise in self.fetchSignInMethods(forEmail: email) { signInMethods, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let signInMethods = signInMethods { + } else if let signInMethods { promise(.success(signInMethods)) } } @@ -309,7 +309,7 @@ public extension Auth { newPassword: String) -> Future { Future { promise in self.confirmPasswordReset(withCode: code, newPassword: newPassword) { error in - if let error = error { + if let error { promise(.failure(error)) } else { promise(.success(())) @@ -332,9 +332,9 @@ public extension Auth { func verifyPasswordResetCode(_ code: String) -> Future { Future { promise in self.verifyPasswordResetCode(code) { email, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let email = email { + } else if let email { promise(.success(email)) } } @@ -353,9 +353,9 @@ public extension Auth { func checkActionCode(code: String) -> Future { Future { promise in self.checkActionCode(code) { actionCodeInfo, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let actionCodeInfo = actionCodeInfo { + } else if let actionCodeInfo { promise(.success(actionCodeInfo)) } } @@ -376,7 +376,7 @@ public extension Auth { func applyActionCode(code: String) -> Future { Future { promise in self.applyActionCode(code) { error in - if let error = error { + if let error { promise(.failure(error)) } else { promise(.success(())) @@ -405,7 +405,7 @@ public extension Auth { func sendPasswordReset(withEmail email: String) -> Future { Future { promise in self.sendPasswordReset(withEmail: email) { error in - if let error = error { + if let error { promise(.failure(error)) } else { promise(.success(())) @@ -448,7 +448,7 @@ public extension Auth { actionCodeSettings: ActionCodeSettings) -> Future { Future { promise in self.sendPasswordReset(withEmail: email, actionCodeSettings: actionCodeSettings) { error in - if let error = error { + if let error { promise(.failure(error)) } else { promise(.success(())) @@ -506,9 +506,9 @@ public extension Auth { uiDelegate: AuthUIDelegate?) -> Future { Future { promise in self.signIn(with: provider, uiDelegate: uiDelegate) { authDataResult, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let authDataResult = authDataResult { + } else if let authDataResult { promise(.success(authDataResult)) } } @@ -534,9 +534,9 @@ public extension Auth { func signIn(withCustomToken token: String) -> Future { Future { promise in self.signIn(withCustomToken: token) { authDataResult, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let authDataResult = authDataResult { + } else if let authDataResult { promise(.success(authDataResult)) } } @@ -583,9 +583,9 @@ public extension Auth { func signIn(with credential: AuthCredential) -> Future { Future { promise in self.signIn(with: credential) { authDataResult, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let authDataResult = authDataResult { + } else if let authDataResult { promise(.success(authDataResult)) } } diff --git a/FirebaseCombineSwift/Sources/Auth/GameCenterAuthProvider+Combine.swift b/FirebaseCombineSwift/Sources/Auth/GameCenterAuthProvider+Combine.swift index 8cf2c7acbf5..95491fbc5df 100644 --- a/FirebaseCombineSwift/Sources/Auth/GameCenterAuthProvider+Combine.swift +++ b/FirebaseCombineSwift/Sources/Auth/GameCenterAuthProvider+Combine.swift @@ -30,9 +30,9 @@ class func getCredential() -> Future { Future { promise in self.getCredential { authCredential, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let authCredential = authCredential { + } else if let authCredential { promise(.success(authCredential)) } } diff --git a/FirebaseCombineSwift/Sources/Auth/MultiFactor+Combine.swift b/FirebaseCombineSwift/Sources/Auth/MultiFactor+Combine.swift index 870e67c9025..4fd850da1e6 100644 --- a/FirebaseCombineSwift/Sources/Auth/MultiFactor+Combine.swift +++ b/FirebaseCombineSwift/Sources/Auth/MultiFactor+Combine.swift @@ -34,9 +34,9 @@ func getSession() -> Future { Future { promise in self.getSessionWithCompletion { session, error in - if let session = session { + if let session { promise(.success(session)) - } else if let error = error { + } else if let error { promise(.failure(error)) } } @@ -59,7 +59,7 @@ displayName: String?) -> Future { Future { promise in self.enroll(with: assertion, displayName: displayName) { error in - if let error = error { + if let error { promise(.failure(error)) } else { promise(.success(())) @@ -81,7 +81,7 @@ func unenroll(with factorInfo: MultiFactorInfo) -> Future { Future { promise in self.unenroll(with: factorInfo) { error in - if let error = error { + if let error { promise(.failure(error)) } else { promise(.success(())) @@ -101,7 +101,7 @@ func unenroll(withFactorUID factorUID: String) -> Future { Future { promise in self.unenroll(withFactorUID: factorUID) { error in - if let error = error { + if let error { promise(.failure(error)) } else { promise(.success(())) diff --git a/FirebaseCombineSwift/Sources/Auth/MultiFactorResolver+Combine.swift b/FirebaseCombineSwift/Sources/Auth/MultiFactorResolver+Combine.swift index 4d27a90cd3d..b2ada743c66 100644 --- a/FirebaseCombineSwift/Sources/Auth/MultiFactorResolver+Combine.swift +++ b/FirebaseCombineSwift/Sources/Auth/MultiFactorResolver+Combine.swift @@ -33,9 +33,9 @@ -> Future { Future { promise in self.resolveSignIn(with: assertion) { authDataResult, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let authDataResult = authDataResult { + } else if let authDataResult { promise(.success(authDataResult)) } } diff --git a/FirebaseCombineSwift/Sources/Auth/OAuthProvider+Combine.swift b/FirebaseCombineSwift/Sources/Auth/OAuthProvider+Combine.swift index 6d14564a05e..05faa7bbd77 100644 --- a/FirebaseCombineSwift/Sources/Auth/OAuthProvider+Combine.swift +++ b/FirebaseCombineSwift/Sources/Auth/OAuthProvider+Combine.swift @@ -33,9 +33,9 @@ -> Future { Future { promise in self.getCredentialWith(uiDelegate) { authCredential, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let authCredential = authCredential { + } else if let authCredential { promise(.success(authCredential)) } } diff --git a/FirebaseCombineSwift/Sources/Auth/PhoneAuthProvider+Combine.swift b/FirebaseCombineSwift/Sources/Auth/PhoneAuthProvider+Combine.swift index 130734c1c63..93af631104d 100644 --- a/FirebaseCombineSwift/Sources/Auth/PhoneAuthProvider+Combine.swift +++ b/FirebaseCombineSwift/Sources/Auth/PhoneAuthProvider+Combine.swift @@ -54,9 +54,9 @@ -> Future { Future { promise in self.verifyPhoneNumber(phoneNumber, uiDelegate: uiDelegate) { verificationID, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let verificationID = verificationID { + } else if let verificationID { promise(.success(verificationID)) } } @@ -99,9 +99,9 @@ uiDelegate: uiDelegate, multiFactorSession: multiFactorSession ) { verificationID, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let verificationID = verificationID { + } else if let verificationID { promise(.success(verificationID)) } } @@ -131,9 +131,9 @@ self.verifyPhoneNumber(with: phoneMultiFactorInfo, uiDelegate: uiDelegate, multiFactorSession: multiFactorSession) { verificationID, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let verificationID = verificationID { + } else if let verificationID { promise(.success(verificationID)) } } diff --git a/FirebaseCombineSwift/Sources/Auth/User+Combine.swift b/FirebaseCombineSwift/Sources/Auth/User+Combine.swift index 4dfb4fb7d53..114f0bd7130 100644 --- a/FirebaseCombineSwift/Sources/Auth/User+Combine.swift +++ b/FirebaseCombineSwift/Sources/Auth/User+Combine.swift @@ -41,9 +41,9 @@ func link(with credential: AuthCredential) -> Future { Future { promise in self.link(with: credential) { authDataResult, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let authDataResult = authDataResult { + } else if let authDataResult { promise(.success(authDataResult)) } } @@ -89,9 +89,9 @@ func reauthenticate(with credential: AuthCredential) -> Future { Future { promise in self.reauthenticate(with: credential) { authDataResult, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let authDataResult = authDataResult { + } else if let authDataResult { promise(.success(authDataResult)) } } @@ -119,9 +119,9 @@ func unlink(fromProvider provider: String) -> Future { Future { promise in self.unlink(fromProvider: provider) { user, error in - if let user = user { + if let user { promise(.success(user)) - } else if let error = error { + } else if let error { promise(.failure(error)) } } @@ -149,7 +149,7 @@ func sendEmailVerification() -> Future { Future { promise in self.sendEmailVerification { error in - if let error = error { + if let error { promise(.failure(error)) } else { promise(.success(())) @@ -188,7 +188,7 @@ -> Future { Future { promise in self.sendEmailVerification(with: actionCodeSettings) { error in - if let error = error { + if let error { promise(.failure(error)) } else { promise(.success(())) diff --git a/FirebaseCombineSwift/Sources/Firestore/CollectionReference+Combine.swift b/FirebaseCombineSwift/Sources/Firestore/CollectionReference+Combine.swift index 32dc0004dc7..7c6c482cb4f 100644 --- a/FirebaseCombineSwift/Sources/Firestore/CollectionReference+Combine.swift +++ b/FirebaseCombineSwift/Sources/Firestore/CollectionReference+Combine.swift @@ -40,9 +40,9 @@ var reference: DocumentReference? return Future { promise in reference = self.addDocument(data: data) { error in - if let error = error { + if let error { promise(.failure(error)) - } else if let reference = reference { + } else if let reference { promise(.success(reference)) } } @@ -70,9 +70,9 @@ return Future { promise in do { try reference = self.addDocument(from: value, encoder: encoder) { error in - if let error = error { + if let error { promise(.failure(error)) - } else if let reference = reference { + } else if let reference { promise(.success(reference)) } } diff --git a/FirebaseCombineSwift/Sources/Firestore/DocumentReference+Combine.swift b/FirebaseCombineSwift/Sources/Firestore/DocumentReference+Combine.swift index 5d853fde1c1..b9dd5568d77 100644 --- a/FirebaseCombineSwift/Sources/Firestore/DocumentReference+Combine.swift +++ b/FirebaseCombineSwift/Sources/Firestore/DocumentReference+Combine.swift @@ -39,7 +39,7 @@ func setData(_ documentData: [String: Any]) -> Future { Future { promise in self.setData(documentData) { error in - if let error = error { + if let error { promise(.failure(error)) } else { promise(.success(())) @@ -62,7 +62,7 @@ func setData(_ documentData: [String: Any], merge: Bool) -> Future { Future { promise in self.setData(documentData, merge: merge) { error in - if let error = error { + if let error { promise(.failure(error)) } else { promise(.success(())) @@ -88,7 +88,7 @@ func setData(_ documentData: [String: Any], mergeFields: [Any]) -> Future { Future { promise in self.setData(documentData, mergeFields: mergeFields) { error in - if let error = error { + if let error { promise(.failure(error)) } else { promise(.success(())) @@ -117,7 +117,7 @@ Future { promise in do { try self.setData(from: value, encoder: encoder) { error in - if let error = error { + if let error { promise(.failure(error)) } else { promise(.success(())) @@ -151,7 +151,7 @@ Future { promise in do { try self.setData(from: value, merge: merge, encoder: encoder) { error in - if let error = error { + if let error { promise(.failure(error)) } else { promise(.success(())) @@ -186,7 +186,7 @@ Future { promise in do { try self.setData(from: value, mergeFields: mergeFields, encoder: encoder) { error in - if let error = error { + if let error { promise(.failure(error)) } else { promise(.success(())) @@ -214,7 +214,7 @@ func updateData(_ documentData: [String: Any]) -> Future { Future { promise in self.updateData(documentData) { error in - if let error = error { + if let error { promise(.failure(error)) } else { promise(.success(())) @@ -233,7 +233,7 @@ func delete() -> Future { Future { promise in self.delete { error in - if let error = error { + if let error { promise(.failure(error)) } else { promise(.success(())) @@ -254,9 +254,9 @@ -> Future { Future { promise in self.getDocument(source: source) { snapshot, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let snapshot = snapshot { + } else if let snapshot { promise(.success(snapshot)) } } @@ -275,9 +275,9 @@ let subject = PassthroughSubject() let listenerHandle = addSnapshotListener(includeMetadataChanges: includeMetadataChanges) { snapshot, error in - if let error = error { + if let error { subject.send(completion: .failure(error)) - } else if let snapshot = snapshot { + } else if let snapshot { subject.send(snapshot) } } diff --git a/FirebaseCombineSwift/Sources/Firestore/Query+Combine.swift b/FirebaseCombineSwift/Sources/Firestore/Query+Combine.swift index 5ad9b8587fc..5d6477b7c45 100644 --- a/FirebaseCombineSwift/Sources/Firestore/Query+Combine.swift +++ b/FirebaseCombineSwift/Sources/Firestore/Query+Combine.swift @@ -32,9 +32,9 @@ func getDocuments(source: FirestoreSource = .default) -> Future { Future { promise in self.getDocuments(source: source) { snapshot, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let snapshot = snapshot { + } else if let snapshot { promise(.success(snapshot)) } } @@ -53,9 +53,9 @@ let subject = PassthroughSubject() let listenerHandle = addSnapshotListener(includeMetadataChanges: includeMetadataChanges) { snapshot, error in - if let error = error { + if let error { subject.send(completion: .failure(error)) - } else if let snapshot = snapshot { + } else if let snapshot { subject.send(snapshot) } } diff --git a/FirebaseCombineSwift/Sources/Firestore/Transaction+Combine.swift b/FirebaseCombineSwift/Sources/Firestore/Transaction+Combine.swift index 523f582cb71..02b584c0ee0 100644 --- a/FirebaseCombineSwift/Sources/Firestore/Transaction+Combine.swift +++ b/FirebaseCombineSwift/Sources/Firestore/Transaction+Combine.swift @@ -64,7 +64,7 @@ return nil } }) { value, error in - if let error = error { + if let error { promise(.failure(error)) } else if let value = value as? T { promise(.success(value)) diff --git a/FirebaseCombineSwift/Sources/Firestore/WriteBatch+Combine.swift b/FirebaseCombineSwift/Sources/Firestore/WriteBatch+Combine.swift index c9740fac853..87ed5ce9ec5 100644 --- a/FirebaseCombineSwift/Sources/Firestore/WriteBatch+Combine.swift +++ b/FirebaseCombineSwift/Sources/Firestore/WriteBatch+Combine.swift @@ -30,7 +30,7 @@ func commit() -> Future { Future { promise in self.commit { error in - if let error = error { + if let error { promise(.failure(error)) } else { promise(.success(())) diff --git a/FirebaseCombineSwift/Sources/Functions/HTTPSCallable+Combine.swift b/FirebaseCombineSwift/Sources/Functions/HTTPSCallable+Combine.swift index 7841583a3a9..f30e9083f76 100644 --- a/FirebaseCombineSwift/Sources/Functions/HTTPSCallable+Combine.swift +++ b/FirebaseCombineSwift/Sources/Functions/HTTPSCallable+Combine.swift @@ -42,9 +42,9 @@ func call() -> Future { Future { promise in self.call { callableResult, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let callableResult = callableResult { + } else if let callableResult { promise(.success(callableResult)) } } @@ -78,9 +78,9 @@ func call(_ data: Any?) -> Future { Future { promise in self.call(data) { callableResult, error in - if let error = error { + if let error { promise(.failure(error)) - } else if let callableResult = callableResult { + } else if let callableResult { promise(.success(callableResult)) } } diff --git a/FirebaseCombineSwift/Sources/Storage/StorageReference+Combine.swift b/FirebaseCombineSwift/Sources/Storage/StorageReference+Combine.swift index 8a96e355602..9a96ae02b43 100644 --- a/FirebaseCombineSwift/Sources/Storage/StorageReference+Combine.swift +++ b/FirebaseCombineSwift/Sources/Storage/StorageReference+Combine.swift @@ -276,7 +276,7 @@ func delete() -> Future { Future { promise in self.delete { error in - if let error = error { + if let error { promise(.failure(error)) } else { promise(.success(true)) diff --git a/FirebaseCombineSwift/Tests/Integration/Storage/StorageIntegration.swift b/FirebaseCombineSwift/Tests/Integration/Storage/StorageIntegration.swift index be8482d3564..d469a9e08a5 100644 --- a/FirebaseCombineSwift/Tests/Integration/Storage/StorageIntegration.swift +++ b/FirebaseCombineSwift/Tests/Integration/Storage/StorageIntegration.swift @@ -633,7 +633,7 @@ class StorageIntegration: XCTestCase { let kFIRStorageIntegrationTestTimeout = 30.0 waitForExpectations(timeout: kFIRStorageIntegrationTestTimeout, handler: { error in - if let error = error { + if let error { print(error) } }) diff --git a/FirebaseCombineSwift/Tests/Unit/Auth/AuthStateDidChangePublisherTests.swift b/FirebaseCombineSwift/Tests/Unit/Auth/AuthStateDidChangePublisherTests.swift index d25e97be74d..ec887693697 100644 --- a/FirebaseCombineSwift/Tests/Unit/Auth/AuthStateDidChangePublisherTests.swift +++ b/FirebaseCombineSwift/Tests/Unit/Auth/AuthStateDidChangePublisherTests.swift @@ -171,7 +171,7 @@ class AuthStateDidChangePublisherTests: XCTestCase { .sink { user in print("Running on the main thread? \(Thread.isMainThread)") - if let user = user, user.isAnonymous { + if let user, user.isAnonymous { signedInExpectation.fulfill() } } @@ -191,7 +191,7 @@ class AuthStateDidChangePublisherTests: XCTestCase { let cancellable = Auth.auth().authStateDidChangePublisher() .sink { user in - if let user = user, user.isAnonymous { + if let user, user.isAnonymous { expect.fulfill() } } @@ -225,7 +225,7 @@ class AuthStateDidChangePublisherTests: XCTestCase { expect.fulfill() } } else { - if let user = user, user.isAnonymous { + if let user, user.isAnonymous { expect.fulfill() } } @@ -261,7 +261,7 @@ class AuthStateDidChangePublisherTests: XCTestCase { expect.fulfill() } } else { - if let user = user, user.isAnonymous { + if let user, user.isAnonymous { expect.fulfill() } } diff --git a/FirebaseCombineSwift/Tests/Unit/Auth/IDTokenDidChangePublisherTests.swift b/FirebaseCombineSwift/Tests/Unit/Auth/IDTokenDidChangePublisherTests.swift index cc532f88d90..1e96ad59592 100644 --- a/FirebaseCombineSwift/Tests/Unit/Auth/IDTokenDidChangePublisherTests.swift +++ b/FirebaseCombineSwift/Tests/Unit/Auth/IDTokenDidChangePublisherTests.swift @@ -113,7 +113,7 @@ class IDTokenDidChangePublisherTests: XCTestCase { cancellable = Auth.auth() .idTokenDidChangePublisher() .sink { user in - if let user = user, user.isAnonymous { + if let user, user.isAnonymous { expect.fulfill() } } @@ -129,7 +129,7 @@ class IDTokenDidChangePublisherTests: XCTestCase { cancellable = Auth.auth() .idTokenDidChangePublisher() .sink { user in - if let user = user, user.isAnonymous { + if let user, user.isAnonymous { print(#function) expect.fulfill() } @@ -161,7 +161,7 @@ class IDTokenDidChangePublisherTests: XCTestCase { expect.fulfill() } } else { - if let user = user, user.isAnonymous { + if let user, user.isAnonymous { expect.fulfill() } } @@ -195,7 +195,7 @@ class IDTokenDidChangePublisherTests: XCTestCase { expect.fulfill() } } else { - if let user = user, user.isAnonymous { + if let user, user.isAnonymous { expect.fulfill() } } diff --git a/FirebaseCombineSwift/Tests/Unit/Auth/SignInWithGameCenterTests.swift b/FirebaseCombineSwift/Tests/Unit/Auth/SignInWithGameCenterTests.swift index a54b932eaa7..ba45270d44d 100644 --- a/FirebaseCombineSwift/Tests/Unit/Auth/SignInWithGameCenterTests.swift +++ b/FirebaseCombineSwift/Tests/Unit/Auth/SignInWithGameCenterTests.swift @@ -73,7 +73,7 @@ class SignInWithGameCenterTests: XCTestCase { body: Data?, contentType: String, completionHandler handler: @escaping FIRAuthBackendRPCIssuerCompletionHandler) { requestURL = URL - if let body = body { + if let body { requestData = body let json = try! JSONSerialization .jsonObject(with: body, options: []) as! [String: Any] diff --git a/FirebaseCombineSwift/Tests/Unit/AuthBackend+Combine.swift b/FirebaseCombineSwift/Tests/Unit/AuthBackend+Combine.swift index 51be478373f..a0bba79d644 100644 --- a/FirebaseCombineSwift/Tests/Unit/AuthBackend+Combine.swift +++ b/FirebaseCombineSwift/Tests/Unit/AuthBackend+Combine.swift @@ -22,9 +22,9 @@ extension FIRAuthBackend { -> Future { Future { promise in self.signIn(withGameCenter: request) { response, error in - if let response = response { + if let response { promise(.success(response)) - } else if let error = error { + } else if let error { promise(.failure(error)) } } diff --git a/FirebaseCore.podspec b/FirebaseCore.podspec index bb2cb898364..517ba503d23 100644 --- a/FirebaseCore.podspec +++ b/FirebaseCore.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseCore' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Firebase Core' s.description = <<-DESC diff --git a/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatStorage.swift b/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatStorage.swift index 41572a0dc44..d400944d055 100644 --- a/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatStorage.swift +++ b/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatStorage.swift @@ -153,7 +153,7 @@ final class HeartbeatStorage: HeartbeatStorageProtocol { /// - heartbeatsBundle: The heartbeats bundle to encode and save. /// - storage: The storage container to write to. private func save(_ heartbeatsBundle: HeartbeatsBundle?, to storage: Storage) throws { - if let heartbeatsBundle = heartbeatsBundle { + if let heartbeatsBundle { let data = try heartbeatsBundle.encoded(using: encoder) try storage.write(data) } else { diff --git a/FirebaseCore/Internal/Sources/HeartbeatLogging/Storage.swift b/FirebaseCore/Internal/Sources/HeartbeatLogging/Storage.swift index 79cf1274b43..a4cac33e27a 100644 --- a/FirebaseCore/Internal/Sources/HeartbeatLogging/Storage.swift +++ b/FirebaseCore/Internal/Sources/HeartbeatLogging/Storage.swift @@ -71,7 +71,7 @@ final class FileStorage: Storage { func write(_ data: Data?) throws { do { try createDirectories(in: url.deletingLastPathComponent()) - if let data = data { + if let data { try data.write(to: url, options: .atomic) } else { let emptyData = Data() @@ -136,7 +136,7 @@ final class UserDefaultsStorage: Storage { /// /// - Parameter data: The `Data?` to write to this object's associated defaults. func write(_ data: Data?) throws { - if let data = data { + if let data { defaults.set(data, forKey: key) } else { defaults.removeObject(forKey: key) diff --git a/FirebaseCore/Internal/Tests/Unit/HeartbeatStorageTests.swift b/FirebaseCore/Internal/Tests/Unit/HeartbeatStorageTests.swift index 51d97672e70..6cff37c608c 100644 --- a/FirebaseCore/Internal/Tests/Unit/HeartbeatStorageTests.swift +++ b/FirebaseCore/Internal/Tests/Unit/HeartbeatStorageTests.swift @@ -283,7 +283,7 @@ private class StorageFake: Storage { var onWrite: ((Data?) throws -> Void)? func read() throws -> Data { - if let onRead = onRead { + if let onRead { return try onRead() } else if let data = fakeFile { return data @@ -293,7 +293,7 @@ private class StorageFake: Storage { } func write(_ data: Data?) throws { - if let onWrite = onWrite { + if let onWrite { return try onWrite(data) } else { fakeFile = data diff --git a/FirebaseCore/Sources/FIRApp.m b/FirebaseCore/Sources/FIRApp.m index a8cc38c12de..c942cecfe51 100644 --- a/FirebaseCore/Sources/FIRApp.m +++ b/FirebaseCore/Sources/FIRApp.m @@ -829,7 +829,7 @@ + (void)registerSwiftComponents { @"FIRSessions" : @"fire-ses", @"FIRFunctionsComponent" : @"fire-fun", @"FIRStorageComponent" : @"fire-str", - @"FIRVertexAIComponent" : @"fire-vtx", + @"FIRVertexAIComponent" : @"fire-vertex", }; for (NSString *className in swiftComponents.allKeys) { Class klass = NSClassFromString(className); @@ -856,7 +856,7 @@ + (void)registerSwiftComponents { #pragma mark - App Life Cycle - (void)subscribeForAppDidBecomeActiveNotifications { -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION NSNotificationName notificationName = UIApplicationDidBecomeActiveNotification; #elif TARGET_OS_OSX NSNotificationName notificationName = NSApplicationDidBecomeActiveNotification; diff --git a/FirebaseCore/Sources/FIROptions.m b/FirebaseCore/Sources/FIROptions.m index d46b657501c..c0625a8bac9 100644 --- a/FirebaseCore/Sources/FIROptions.m +++ b/FirebaseCore/Sources/FIROptions.m @@ -284,7 +284,7 @@ - (NSString *)libraryVersionID { // The unit tests are set up to catch anything that does not properly convert. NSString *version = FIRFirebaseVersion(); NSArray *components = [version componentsSeparatedByString:@"."]; - NSString *major = [components objectAtIndex:0]; + NSString *major = [NSString stringWithFormat:@"%02d", [[components objectAtIndex:0] intValue]]; NSString *minor = [NSString stringWithFormat:@"%02d", [[components objectAtIndex:1] intValue]]; NSString *patch = [NSString stringWithFormat:@"%02d", [[components objectAtIndex:2] intValue]]; kFIRLibraryVersionID = [NSString stringWithFormat:@"%@%@%@000", major, minor, patch]; diff --git a/FirebaseCore/Tests/Unit/FIRAppTest.m b/FirebaseCore/Tests/Unit/FIRAppTest.m index 285c76500c3..b231e608b92 100644 --- a/FirebaseCore/Tests/Unit/FIRAppTest.m +++ b/FirebaseCore/Tests/Unit/FIRAppTest.m @@ -862,7 +862,7 @@ - (XCTestExpectation *)expectNotificationNamed:(NSNotificationName)name } - (NSNotificationName)appDidBecomeActiveNotificationName { -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION return UIApplicationDidBecomeActiveNotification; #elif TARGET_OS_OSX return NSApplicationDidBecomeActiveNotification; diff --git a/FirebaseCore/Tests/Unit/FIROptionsTest.m b/FirebaseCore/Tests/Unit/FIROptionsTest.m index 3de059f4191..fd5c901598f 100644 --- a/FirebaseCore/Tests/Unit/FIROptionsTest.m +++ b/FirebaseCore/Tests/Unit/FIROptionsTest.m @@ -624,7 +624,7 @@ - (void)testVersionConsistency { int minor = (versionString[2] - '0') * 10 + versionString[3] - '0'; int patch = (versionString[4] - '0') * 10 + versionString[5] - '0'; NSString *str = [NSString stringWithFormat:@"%d.%d.%d", major, minor, patch]; - XCTAssertEqualObjects(str, FIRFirebaseVersion()); + XCTAssertTrue([FIRFirebaseVersion() hasPrefix:str]); } // Repeat test with more Objective-C. @@ -638,11 +638,11 @@ - (void)testVersionConsistency2 { NSRange major = NSMakeRange(0, 2); NSRange minor = NSMakeRange(2, 2); NSRange patch = NSMakeRange(4, 2); - NSString *str = - [NSString stringWithFormat:@"%@.%d.%d", [kFIRLibraryVersionID substringWithRange:major], - [[kFIRLibraryVersionID substringWithRange:minor] intValue], - [[kFIRLibraryVersionID substringWithRange:patch] intValue]]; - XCTAssertEqualObjects(str, FIRFirebaseVersion()); + NSString *str = [NSString + stringWithFormat:@"%d.%d.%d", [[kFIRLibraryVersionID substringWithRange:major] intValue], + [[kFIRLibraryVersionID substringWithRange:minor] intValue], + [[kFIRLibraryVersionID substringWithRange:patch] intValue]]; + XCTAssertTrue([FIRFirebaseVersion() hasPrefix:str]); } #pragma mark - Helpers diff --git a/FirebaseCoreExtension.podspec b/FirebaseCoreExtension.podspec index 4e7da0eb53c..0b1480dd9c9 100644 --- a/FirebaseCoreExtension.podspec +++ b/FirebaseCoreExtension.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseCoreExtension' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Extended FirebaseCore APIs for Firebase product SDKs' s.description = <<-DESC diff --git a/FirebaseCoreInternal.podspec b/FirebaseCoreInternal.podspec index 2cb42104375..10ff13f66db 100644 --- a/FirebaseCoreInternal.podspec +++ b/FirebaseCoreInternal.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseCoreInternal' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'APIs for internal FirebaseCore usage.' s.description = <<-DESC diff --git a/FirebaseCrashlytics.podspec b/FirebaseCrashlytics.podspec index 1ca34f21665..38d5a760312 100644 --- a/FirebaseCrashlytics.podspec +++ b/FirebaseCrashlytics.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseCrashlytics' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Best and lightest-weight crash reporting for mobile, desktop and tvOS.' s.description = 'Firebase Crashlytics helps you track, prioritize, and fix stability issues that erode app quality.' s.homepage = 'https://firebase.google.com/' diff --git a/FirebaseDatabase.podspec b/FirebaseDatabase.podspec index e6e0f7a20fa..12af9ce7905 100644 --- a/FirebaseDatabase.podspec +++ b/FirebaseDatabase.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseDatabase' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Firebase Realtime Database' s.description = <<-DESC diff --git a/FirebaseDatabase/CHANGELOG.md b/FirebaseDatabase/CHANGELOG.md index 61df131aa31..2763dc0c9f9 100644 --- a/FirebaseDatabase/CHANGELOG.md +++ b/FirebaseDatabase/CHANGELOG.md @@ -1,3 +1,7 @@ +# 10.27.0 +- [changed] Update internal socket implementation to use `NSURLSessionWebSocket` where + available. (#12883) + # 10.25.0 - [changed] Removed usages of user defaults API to eliminate required reason impact. diff --git a/FirebaseDatabase/Sources/Core/FPersistentConnection.m b/FirebaseDatabase/Sources/Core/FPersistentConnection.m index 3d1e8af9053..da2820d5deb 100644 --- a/FirebaseDatabase/Sources/Core/FPersistentConnection.m +++ b/FirebaseDatabase/Sources/Core/FPersistentConnection.m @@ -1256,8 +1256,7 @@ - (void)sendStats:(NSDictionary *)stats { - (void)sendConnectStats { NSMutableDictionary *stats = [NSMutableDictionary dictionary]; -#if TARGET_OS_IOS || TARGET_OS_TV || \ - (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION if (self.config.persistenceEnabled) { stats[@"persistence.ios.enabled"] = @1; } diff --git a/FirebaseDatabase/Sources/Core/FRepo.m b/FirebaseDatabase/Sources/Core/FRepo.m index 00b0850cd17..628de6a719a 100644 --- a/FirebaseDatabase/Sources/Core/FRepo.m +++ b/FirebaseDatabase/Sources/Core/FRepo.m @@ -52,8 +52,7 @@ #import "FirebaseDatabase/Sources/Utilities/Tuples/FTupleTransaction.h" #import -#if TARGET_OS_IOS || TARGET_OS_TV || \ - (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import #endif @@ -816,8 +815,7 @@ - (void)didEnterBackground { // Targetted compilation is ONLY for testing. UIKit is weak-linked in actual // release build. -#if TARGET_OS_IOS || TARGET_OS_TV || \ - (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION // The idea is to wait until any outstanding sets get written to disk. Since // the sets might still be in our dispatch queue, we wait for the dispatch // queue to catch up and for persistence to catch up. This may be diff --git a/FirebaseDatabase/Sources/Persistence/FLevelDBStorageEngine.m b/FirebaseDatabase/Sources/Persistence/FLevelDBStorageEngine.m index 6516baa43c7..4dd808da3a1 100644 --- a/FirebaseDatabase/Sources/Persistence/FLevelDBStorageEngine.m +++ b/FirebaseDatabase/Sources/Persistence/FLevelDBStorageEngine.m @@ -275,8 +275,7 @@ - (void)close { } + (NSString *)firebaseDir { -#if TARGET_OS_IOS || TARGET_OS_WATCH || \ - (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_WATCH || TARGET_OS_VISION NSArray *dirPaths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDir = [dirPaths objectAtIndex:0]; diff --git a/FirebaseDatabase/Sources/Realtime/FWebSocketConnection.h b/FirebaseDatabase/Sources/Realtime/FWebSocketConnection.h index 676971864cb..14912ff861f 100644 --- a/FirebaseDatabase/Sources/Realtime/FWebSocketConnection.h +++ b/FirebaseDatabase/Sources/Realtime/FWebSocketConnection.h @@ -23,7 +23,8 @@ @protocol FWebSocketDelegate; #if !TARGET_OS_WATCH -@interface FWebSocketConnection : NSObject +@interface FWebSocketConnection + : NSObject #else @interface FWebSocketConnection : NSObject #endif // else !TARGET_OS_WATCH diff --git a/FirebaseDatabase/Sources/Realtime/FWebSocketConnection.m b/FirebaseDatabase/Sources/Realtime/FWebSocketConnection.m index 5ac1bfa2f85..171b75156a9 100644 --- a/FirebaseDatabase/Sources/Realtime/FWebSocketConnection.m +++ b/FirebaseDatabase/Sources/Realtime/FWebSocketConnection.m @@ -26,16 +26,17 @@ #import "FirebaseDatabase/Sources/Realtime/FWebSocketConnection.h" #import "FirebaseDatabase/Sources/Utilities/FStringUtilities.h" -#if TARGET_OS_IOS || TARGET_OS_TV || \ - (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && - // TARGET_OS_VISION) -#if TARGET_OS_WATCH -#import +#elif TARGET_OS_WATCH #import -#endif // TARGET_OS_WATCH + +#elif TARGET_OS_OSX +#import +#endif + +#import static NSString *const kAppCheckTokenHeader = @"X-Firebase-AppCheck"; static NSString *const kUserAgentHeader = @"User-Agent"; @@ -52,9 +53,10 @@ - (void)shutdown; - (void)onClosed; - (void)closeIfNeverConnected; -#if TARGET_OS_WATCH -@property(nonatomic, strong) NSURLSessionWebSocketTask *webSocketTask; -#else +@property(nonatomic, strong) + NSURLSessionWebSocketTask *webSocketTask API_AVAILABLE( + macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)); +#if !TARGET_OS_WATCH @property(nonatomic, strong) FSRWebSocket *webSocket; #endif // TARGET_OS_WATCH @property(nonatomic, strong) NSNumber *connectionId; @@ -100,40 +102,56 @@ - (instancetype)initWith:(FRepoInfo *)repoInfo userAgent:userAgent googleAppID:googleAppID appCheckToken:appCheckToken]; -#if TARGET_OS_WATCH - // Regular NSURLSession websocket. - NSOperationQueue *opQueue = [[NSOperationQueue alloc] init]; - opQueue.underlyingQueue = queue; - NSURLSession *session = [NSURLSession - sessionWithConfiguration:[NSURLSessionConfiguration - defaultSessionConfiguration] - delegate:self - delegateQueue:opQueue]; - NSURLSessionWebSocketTask *task = - [session webSocketTaskWithRequest:req]; - self.webSocketTask = task; - - if (@available(watchOS 7.0, *)) { - [[NSNotificationCenter defaultCenter] - addObserverForName:WKApplicationWillResignActiveNotification - object:nil - queue:opQueue - usingBlock:^(NSNotification *_Nonnull note) { - FFLog(@"I-RDB083015", - @"Received watchOS background notification, " - @"closing web socket."); - [self onClosed]; - }]; + + if (@available(iOS 13.0, macOS 10.15, macCatalyst 13.1, tvOS 13.0, + watchOS 6.0, *)) { + // Regular NSURLSession websocket. + NSOperationQueue *opQueue = [[NSOperationQueue alloc] init]; + opQueue.underlyingQueue = queue; + NSURLSession *session = [NSURLSession + sessionWithConfiguration:[NSURLSessionConfiguration + defaultSessionConfiguration] + delegate:self + delegateQueue:opQueue]; + NSURLSessionWebSocketTask *task = + [session webSocketTaskWithRequest:req]; + self.webSocketTask = task; + +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION || TARGET_OS_MACCATALYST + NSString *resignName = UIApplicationWillResignActiveNotification; +#elif TARGET_OS_OSX + NSString *resignName = NSApplicationWillResignActiveNotification; +#elif TARGET_OS_WATCH + NSString *resignName = WKApplicationWillResignActiveNotification; +#elif +#error("missing platform") +#endif + if (@available(watchOS 7.0, *)) { + [[NSNotificationCenter defaultCenter] + addObserverForName:resignName + object:nil + queue:opQueue + usingBlock:^(NSNotification *_Nonnull note) { + FFLog(@"I-RDB083015", + @"Received notification that application " + @"will resign, " + @"closing web socket."); + [self onClosed]; + }]; + } + } +#if !TARGET_OS_WATCH + else { + // TODO(mmaksym): Remove googleAppID and userAgent from FSRWebSocket + // as they are passed via NSURLRequest. + self.webSocket = + [[FSRWebSocket alloc] initWithURLRequest:req + queue:queue + googleAppID:googleAppID + andUserAgent:userAgent]; + [self.webSocket setDelegateDispatchQueue:queue]; + self.webSocket.delegate = self; } -#else - // TODO(mmaksym): Remove googleAppID and userAgent from FSRWebSocket as - // they are passed via NSURLRequest. - self.webSocket = [[FSRWebSocket alloc] initWithURLRequest:req - queue:queue - googleAppID:googleAppID - andUserAgent:userAgent]; - [self.webSocket setDelegateDispatchQueue:queue]; - self.webSocket.delegate = self; #endif // TARGET_OS_WATCH } return self; @@ -146,8 +164,7 @@ - (NSString *)userAgent { // Targetted compilation is ONLY for testing. UIKit is weak-linked in actual // release build. -#if TARGET_OS_IOS || TARGET_OS_TV || \ - (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION Class uiDeviceClass = NSClassFromString(@"UIDevice"); if (uiDeviceClass) { systemVersion = [uiDeviceClass currentDevice].systemVersion; @@ -195,13 +212,17 @@ - (void)open { assert(delegate); everConnected = NO; // TODO Assert url -#if TARGET_OS_WATCH - [self.webSocketTask resume]; - // We need to request data from the web socket in order for it to start - // sending data. - [self receiveWebSocketData]; -#else - [self.webSocket open]; + if (@available(iOS 13.0, macOS 10.15, macCatalyst 13.1, tvOS 13.0, + watchOS 6.0, *)) { + [self.webSocketTask resume]; + // We need to request data from the web socket in order for it to start + // sending data. + [self receiveWebSocketData]; + } +#if !TARGET_OS_WATCH + else { + [self.webSocket open]; + } #endif // TARGET_OS_WATCH dispatch_time_t when = dispatch_time( DISPATCH_TIME_NOW, kWebsocketConnectTimeout * NSEC_PER_SEC); @@ -214,12 +235,16 @@ - (void)close { FFLog(@"I-RDB083003", @"(wsc:%@) FWebSocketConnection is being closed.", self.connectionId); isClosed = YES; -#if TARGET_OS_WATCH - [self.webSocketTask - cancelWithCloseCode:NSURLSessionWebSocketCloseCodeNormalClosure - reason:nil]; -#else - [self.webSocket close]; + if (@available(iOS 13.0, macOS 10.15, macCatalyst 13.1, tvOS 13.0, + watchOS 6.0, *)) { + [self.webSocketTask + cancelWithCloseCode:NSURLSessionWebSocketCloseCodeNormalClosure + reason:nil]; + } +#if !TARGET_OS_WATCH + else { + [self.webSocket close]; + } #endif // TARGET_OS_WATCH } @@ -322,25 +347,27 @@ - (void)handleIncomingFrame:(NSString *)message { } #pragma mark - -#pragma mark URLSessionWebSocketDelegate watchOS implementation -#if TARGET_OS_WATCH +#pragma mark URLSessionWebSocketDelegate implementation - (void)URLSession:(NSURLSession *)session webSocketTask:(NSURLSessionWebSocketTask *)webSocketTask - didOpenWithProtocol:(NSString *)protocol { + didOpenWithProtocol:(NSString *)protocol + API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) { [self webSocketDidOpen]; } - (void)URLSession:(NSURLSession *)session webSocketTask:(NSURLSessionWebSocketTask *)webSocketTask didCloseWithCode:(NSURLSessionWebSocketCloseCode)closeCode - reason:(NSData *)reason { + reason:(NSData *)reason + API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) { FFLog(@"I-RDB083011", @"(wsc:%@) didCloseWithCode: %ld %@", self.connectionId, (long)closeCode, reason); [self onClosed]; } -- (void)receiveWebSocketData { +- (void)receiveWebSocketData API_AVAILABLE(macos(10.15), ios(13.0), + watchos(6.0), tvos(13.0)) { __weak __auto_type weakSelf = self; [self.webSocketTask receiveMessageWithCompletionHandler:^( NSURLSessionWebSocketMessage *_Nullable message, @@ -364,7 +391,7 @@ - (void)receiveWebSocketData { }]; } -#else +#if !TARGET_OS_WATCH #pragma mark SRWebSocketDelegate implementation @@ -387,7 +414,7 @@ - (void)webSocket:(FSRWebSocket *)webSocket [self onClosed]; } -#endif // TARGET_OS_WATCH +#endif // !TARGET_OS_WATCH // Common to both SRWebSocketDelegate and URLSessionWebSocketDelegate. @@ -413,21 +440,26 @@ - (void)webSocketDidOpen { /** Sends a string through the open web socket. */ - (void)sendStringToWebSocket:(NSString *)string { -#if TARGET_OS_WATCH - // Use built-in URLSessionWebSocket functionality. - [self.webSocketTask sendMessage:[[NSURLSessionWebSocketMessage alloc] - initWithString:string] - completionHandler:^(NSError *_Nullable error) { - if (error) { - FFWarn(@"I-RDB083016", - @"Error sending web socket data: %@.", error); - return; - } - }]; -#else - // Use existing SocketRocket implementation. - [self.webSocket send:string]; -#endif // TARGET_OS_WATCH + if (@available(iOS 13.0, macOS 10.15, macCatalyst 13.1, tvOS 13.0, + watchOS 6.0, *)) { + // Use built-in URLSessionWebSocket functionality. + [self.webSocketTask + sendMessage:[[NSURLSessionWebSocketMessage alloc] + initWithString:string] + completionHandler:^(NSError *_Nullable error) { + if (error) { + FFWarn(@"I-RDB083016", @"Error sending web socket data: %@.", + error); + return; + } + }]; + } +#if !TARGET_OS_WATCH + else { + // Use existing SocketRocket implementation. + [self.webSocket send:string]; + } +#endif // !TARGET_OS_WATCH } /** @@ -446,12 +478,17 @@ - (void)closeIfNeverConnected { if (!everConnected) { FFLog(@"I-RDB083012", @"(wsc:%@) Websocket timed out on connect", self.connectionId); -#if TARGET_OS_WATCH - [self.webSocketTask - cancelWithCloseCode:NSURLSessionWebSocketCloseCodeNoStatusReceived - reason:nil]; -#else - [self.webSocket close]; + if (@available(iOS 13.0, macOS 10.15, macCatalyst 13.1, tvOS 13.0, + watchOS 6.0, *)) { + [self.webSocketTask + cancelWithCloseCode: + NSURLSessionWebSocketCloseCodeNoStatusReceived + reason:nil]; + } +#if !TARGET_OS_WATCH + else { + [self.webSocket close]; + } #endif // TARGET_OS_WATCH } } @@ -468,9 +505,11 @@ - (void)onClosed { FFLog(@"I-RDB083013", @"Websocket is closing itself"); [self shutdown]; } -#if TARGET_OS_WATCH - self.webSocketTask = nil; -#else + if (@available(iOS 13.0, macOS 10.15, macCatalyst 13.1, tvOS 13.0, + watchOS 6.0, *)) { + self.webSocketTask = nil; + } +#if !TARGET_OS_WATCH self.webSocket = nil; #endif // TARGET_OS_WATCH if (keepAlive.isValid) { diff --git a/FirebaseDatabase/Swift/Sources/Codable/DatabaseReference+WriteEncodable.swift b/FirebaseDatabase/Swift/Sources/Codable/DatabaseReference+WriteEncodable.swift index 529fc2e6015..094cb3e2f7c 100644 --- a/FirebaseDatabase/Swift/Sources/Codable/DatabaseReference+WriteEncodable.swift +++ b/FirebaseDatabase/Swift/Sources/Codable/DatabaseReference+WriteEncodable.swift @@ -39,7 +39,7 @@ public extension DatabaseReference { completion: ((Error?) -> Void)? = nil) throws { let encoded = try encoder.encode(value) - if let completion = completion { + if let completion { setValue(encoded, withCompletionBlock: { error, _ in completion(error) }) } else { setValue(encoded) diff --git a/FirebaseDatabase/Swift/Sources/Codable/ServerTimestamp.swift b/FirebaseDatabase/Swift/Sources/Codable/ServerTimestamp.swift index ecfd148879c..a99ba0c637e 100644 --- a/FirebaseDatabase/Swift/Sources/Codable/ServerTimestamp.swift +++ b/FirebaseDatabase/Swift/Sources/Codable/ServerTimestamp.swift @@ -59,7 +59,7 @@ public struct ServerTimestamp: Codable, Equatable, Hashable { public func encode(to encoder: Encoder) throws { var container = encoder.singleValueContainer() - if let value = value { + if let value { let interval = value.timeIntervalSince1970 try container.encode(Int(interval * 1000)) } else { diff --git a/FirebaseDatabase/Tests/Integration/FData.m b/FirebaseDatabase/Tests/Integration/FData.m index 2fa04319f9f..9570cc1c5aa 100644 --- a/FirebaseDatabase/Tests/Integration/FData.m +++ b/FirebaseDatabase/Tests/Integration/FData.m @@ -2197,7 +2197,9 @@ - (void)testUpdateDoesntAffectPriorityRemotely { }]; } -- (void)testUpdateReplacesChildrenAndIsNotRecursive { +// TODO: On arm hardware Macs, the following test hangs with the emulator, but passes with a real +// project. +- (void)SKIPtestUpdateReplacesChildrenAndIsNotRecursive { FTupleFirebase *refs = [FTestHelpers getRandomNodePair]; FIRDatabaseReference *reader = refs.one; FIRDatabaseReference *writer = refs.two; diff --git a/FirebaseDatabase/Tests/Integration/FIRDatabaseQueryTests.m b/FirebaseDatabase/Tests/Integration/FIRDatabaseQueryTests.m index 4163cd15ae6..947d5445dd8 100644 --- a/FirebaseDatabase/Tests/Integration/FIRDatabaseQueryTests.m +++ b/FirebaseDatabase/Tests/Integration/FIRDatabaseQueryTests.m @@ -4419,7 +4419,9 @@ - (void)testGetUpdatesPersistenceCacheWhenEnabled { } } -- (void)testGetSkipsPersistenceCacheWhenOnline { +// TODO: On arm hardware Macs, the following test hangs with the emulator, but passes with a real +// project. +- (void)SKIPtestGetSkipsPersistenceCacheWhenOnline { FIRDatabase* db = [self databaseForURL:self.databaseURL name:[[NSUUID UUID] UUIDString]]; FIRDatabase* db2 = [self databaseForURL:self.databaseURL name:[[NSUUID UUID] UUIDString]]; diff --git a/FirebaseDynamicLinks.podspec b/FirebaseDynamicLinks.podspec index 38ba6239639..aecb9a93884 100644 --- a/FirebaseDynamicLinks.podspec +++ b/FirebaseDynamicLinks.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseDynamicLinks' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Firebase Dynamic Links' s.description = <<-DESC diff --git a/FirebaseDynamicLinks/CHANGELOG.md b/FirebaseDynamicLinks/CHANGELOG.md index 20226346a37..80a0a4105db 100644 --- a/FirebaseDynamicLinks/CHANGELOG.md +++ b/FirebaseDynamicLinks/CHANGELOG.md @@ -1,3 +1,6 @@ +# 10.27.0 +- [added] Added deprecation warning in advance of August 25, 2025 Dynamic Links service shutdown. (#12995) + # 10.3.0 - [fixed] Fixes issue where `utmParametersDictionary` / `minimumAppVersion` were not provided and their value were set to `[NSNull null]` instead of `nil`. diff --git a/FirebaseDynamicLinks/Sources/Public/FirebaseDynamicLinks/FIRDynamicLinks.h b/FirebaseDynamicLinks/Sources/Public/FirebaseDynamicLinks/FIRDynamicLinks.h index 78c8f5d0e81..a23dea44780 100644 --- a/FirebaseDynamicLinks/Sources/Public/FirebaseDynamicLinks/FIRDynamicLinks.h +++ b/FirebaseDynamicLinks/Sources/Public/FirebaseDynamicLinks/FIRDynamicLinks.h @@ -31,7 +31,8 @@ NS_ASSUME_NONNULL_BEGIN * @abstract A class that checks for pending Dynamic Links and parses URLs. * This class is available on iOS only. */ - +DEPRECATED_MSG_ATTRIBUTE( + "Firebase Dynamic Links is deprecated and the service will shut down on August 25, 2025.") NS_EXTENSION_UNAVAILABLE_IOS("Firebase Dynamic Links is not supported for iOS extensions.") API_UNAVAILABLE(macos, tvos, watchos) NS_SWIFT_NAME(DynamicLinks) diff --git a/FirebaseFirestore.podspec b/FirebaseFirestore.podspec index 20385fbf851..edeca1ced9a 100644 --- a/FirebaseFirestore.podspec +++ b/FirebaseFirestore.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseFirestore' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Google Cloud Firestore' s.description = <<-DESC Google Cloud Firestore is a NoSQL document database built for automatic scaling, high performance, and ease of application development. @@ -37,7 +37,7 @@ Google Cloud Firestore is a NoSQL document database built for automatic scaling, s.dependency 'FirebaseCore', '~> 10.0' s.dependency 'FirebaseCoreExtension', '~> 10.0' - s.dependency 'FirebaseFirestoreInternal', '10.25.0' + s.dependency 'FirebaseFirestoreInternal', '10.27.0' s.dependency 'FirebaseSharedSwift', '~> 10.0' end diff --git a/FirebaseFirestoreInternal.podspec b/FirebaseFirestoreInternal.podspec index b6a5f955b6d..0ab90c8b970 100644 --- a/FirebaseFirestoreInternal.podspec +++ b/FirebaseFirestoreInternal.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseFirestoreInternal' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Google Cloud Firestore' s.description = <<-DESC diff --git a/FirebaseFunctions.podspec b/FirebaseFunctions.podspec index 8e7a05bbf5b..95e1c491303 100644 --- a/FirebaseFunctions.podspec +++ b/FirebaseFunctions.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseFunctions' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Cloud Functions for Firebase' s.description = <<-DESC diff --git a/FirebaseFunctions/Sources/Callable+Codable.swift b/FirebaseFunctions/Sources/Callable+Codable.swift index 5a8e508a9f0..08753e75f36 100644 --- a/FirebaseFunctions/Sources/Callable+Codable.swift +++ b/FirebaseFunctions/Sources/Callable+Codable.swift @@ -64,10 +64,10 @@ public struct Callable { callable.call(encoded) { result, error in do { - if let result = result { + if let result { let decoded = try decoder.decode(Response.self, from: result.data) completion(.success(decoded)) - } else if let error = error { + } else if let error { completion(.failure(error)) } else { completion(.failure(CallableError.internalError)) diff --git a/FirebaseFunctions/Sources/Functions.swift b/FirebaseFunctions/Sources/Functions.swift index 14eeb4e4f1b..9eb7a5d6a1e 100644 --- a/FirebaseFunctions/Sources/Functions.swift +++ b/FirebaseFunctions/Sources/Functions.swift @@ -347,12 +347,12 @@ enum FunctionsConstants { assert(!name.isEmpty, "Name cannot be empty") // Check if we're using the emulator - if let emulatorOrigin = emulatorOrigin { + if let emulatorOrigin { return "\(emulatorOrigin)/\(projectID)/\(region)/\(name)" } // Check the custom domain. - if let customDomain = customDomain { + if let customDomain { return "\(customDomain)/\(name)" } @@ -368,7 +368,7 @@ enum FunctionsConstants { contextProvider.getContext(options: options) { context, error in // Note: context is always non-nil since some checks could succeed, we're only failing if // there's an error. - if let error = error { + if let error { completion(.failure(error)) } else { let url = self.urlWithName(name) @@ -391,7 +391,7 @@ enum FunctionsConstants { contextProvider.getContext(options: options) { context, error in // Note: context is always non-nil since some checks could succeed, we're only failing if // there's an error. - if let error = error { + if let error { completion(.failure(error)) } else { self.callFunction(url: url, @@ -480,7 +480,7 @@ enum FunctionsConstants { localError = FunctionsErrorCode.deadlineExceeded.generatedError(userInfo: nil) } // If there was an error, report it to the user and stop. - if let localError = localError { + if let localError { completion(.failure(localError)) } else { completion(.failure(error)) diff --git a/FirebaseFunctions/Sources/FunctionsError.swift b/FirebaseFunctions/Sources/FunctionsError.swift index 8af6df9e077..9da297a9d13 100644 --- a/FirebaseFunctions/Sources/FunctionsError.swift +++ b/FirebaseFunctions/Sources/FunctionsError.swift @@ -219,7 +219,7 @@ func FunctionsErrorForResponse(status: NSInteger, var details: AnyObject? // Then look through the body for explicit details. - if let body = body, + if let body, let json = try? JSONSerialization.jsonObject(with: body) as? NSDictionary, let errorDetails = json["error"] as? NSDictionary { if let status = errorDetails["status"] as? String { @@ -252,7 +252,7 @@ func FunctionsErrorForResponse(status: NSInteger, var userInfo = [String: Any]() userInfo[NSLocalizedDescriptionKey] = description - if let details = details { + if let details { userInfo[FunctionsErrorDetailsKey] = details } return code.generatedError(userInfo: userInfo) diff --git a/FirebaseFunctions/Sources/HTTPSCallable.swift b/FirebaseFunctions/Sources/HTTPSCallable.swift index 8391d153236..629f3949527 100644 --- a/FirebaseFunctions/Sources/HTTPSCallable.swift +++ b/FirebaseFunctions/Sources/HTTPSCallable.swift @@ -151,7 +151,7 @@ open class HTTPSCallable: NSObject { return try await withCheckedThrowingContinuation { continuation in // TODO(bonus): Use task to handle and cancellation. self.call(data) { callableResult, error in - if let callableResult = callableResult { + if let callableResult { continuation.resume(returning: callableResult) } else { continuation.resume(throwing: error!) diff --git a/FirebaseFunctions/Sources/Internal/FunctionsContext.swift b/FirebaseFunctions/Sources/Internal/FunctionsContext.swift index 15591f83329..e4902fbee3b 100644 --- a/FirebaseFunctions/Sources/Internal/FunctionsContext.swift +++ b/FirebaseFunctions/Sources/Internal/FunctionsContext.swift @@ -60,7 +60,7 @@ class FunctionsContextProvider: NSObject { var error: Error? var limitedUseAppCheckToken: String? - if let auth = auth { + if let auth { dispatchGroup.enter() auth.getToken(forcingRefresh: false) { token, authError in @@ -70,7 +70,7 @@ class FunctionsContextProvider: NSObject { } } - if let appCheck = appCheck { + if let appCheck { dispatchGroup.enter() if options?.requireLimitedUseAppCheckTokens == true { diff --git a/FirebaseFunctions/Sources/Internal/FunctionsSerializer.swift b/FirebaseFunctions/Sources/Internal/FunctionsSerializer.swift index 290d9ef38ee..a883ed79f01 100644 --- a/FirebaseFunctions/Sources/Internal/FunctionsSerializer.swift +++ b/FirebaseFunctions/Sources/Internal/FunctionsSerializer.swift @@ -99,7 +99,7 @@ class FUNSerializer: NSObject { } // Throw the internal error that popped up, if it did. - if let decodeError = decodeError { + if let decodeError { throw decodeError } return decoded diff --git a/FirebaseFunctions/Tests/Unit/FunctionsAPITests.swift b/FirebaseFunctions/Tests/Unit/FunctionsAPITests.swift index e419ae5edf9..cde13386136 100644 --- a/FirebaseFunctions/Tests/Unit/FunctionsAPITests.swift +++ b/FirebaseFunctions/Tests/Unit/FunctionsAPITests.swift @@ -78,7 +78,7 @@ final class FunctionsAPITests: XCTestCase { let data: Any? = nil callableRef.call(data) { result, error in - if let result = result { + if let result { _ = result.data } else if let _ /* error */ = error { // ... @@ -98,7 +98,7 @@ final class FunctionsAPITests: XCTestCase { } callableRef.call { result, error in - if let result = result { + if let result { _ = result.data } else if let _ /* error */ = error { // ... @@ -120,7 +120,7 @@ final class FunctionsAPITests: XCTestCase { // MARK: - FunctionsErrorCode callableRef.call { _, error in - if let error = error { + if let error { switch (error as NSError).code { case FunctionsErrorCode.OK.rawValue: break diff --git a/FirebaseInAppMessaging.podspec b/FirebaseInAppMessaging.podspec index 4b16c2a94a1..4a0b346600c 100644 --- a/FirebaseInAppMessaging.podspec +++ b/FirebaseInAppMessaging.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseInAppMessaging' - s.version = '10.25.0-beta' + s.version = '10.27.0-beta' s.summary = 'Firebase In-App Messaging for iOS' s.description = <<-DESC diff --git a/FirebaseInAppMessaging/CHANGELOG.md b/FirebaseInAppMessaging/CHANGELOG.md index 6ed3ff1c7ca..03b535caa4a 100644 --- a/FirebaseInAppMessaging/CHANGELOG.md +++ b/FirebaseInAppMessaging/CHANGELOG.md @@ -1,3 +1,10 @@ +# 10.27.0 +- [fixed] Fixed crash at app start that affected CocoaPods users using static + frameworks (#12882). + +# 10.26.0 +- [fixed] Fixed crash at app start that affected SwiftPM users (#12882). + # 10.25.0 - [changed] Removed usages of user defaults API to eliminate required reason impact. diff --git a/FirebaseInAppMessaging/Sources/Analytics/FIRIAMAnalyticsEventLoggerImpl.m b/FirebaseInAppMessaging/Sources/Analytics/FIRIAMAnalyticsEventLoggerImpl.m index 8176cb83c68..f4f8a8bc577 100644 --- a/FirebaseInAppMessaging/Sources/Analytics/FIRIAMAnalyticsEventLoggerImpl.m +++ b/FirebaseInAppMessaging/Sources/Analytics/FIRIAMAnalyticsEventLoggerImpl.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import @@ -176,4 +176,4 @@ - (void)logAnalyticsEventForType:(FIRIAMAnalyticsLogEventType)eventType } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Analytics/FIRIAMClearcutHttpRequestSender.m b/FirebaseInAppMessaging/Sources/Analytics/FIRIAMClearcutHttpRequestSender.m index 881621eb258..955aab345d4 100644 --- a/FirebaseInAppMessaging/Sources/Analytics/FIRIAMClearcutHttpRequestSender.m +++ b/FirebaseInAppMessaging/Sources/Analytics/FIRIAMClearcutHttpRequestSender.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseCore/Extension/FirebaseCoreInternal.h" @@ -204,4 +204,4 @@ - (void)sendClearcutHttpRequestForLogs:(NSArray *)log } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Analytics/FIRIAMClearcutLogStorage.m b/FirebaseInAppMessaging/Sources/Analytics/FIRIAMClearcutLogStorage.m index 1d94a2de83b..c0610fc5032 100644 --- a/FirebaseInAppMessaging/Sources/Analytics/FIRIAMClearcutLogStorage.m +++ b/FirebaseInAppMessaging/Sources/Analytics/FIRIAMClearcutLogStorage.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import @@ -95,14 +95,12 @@ - (instancetype)initWithExpireAfterInSeconds:(NSInteger)expireInSeconds selector:@selector(appWillBecomeInactive:) name:UIApplicationWillResignActiveNotification object:nil]; -#if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 if (@available(iOS 13.0, tvOS 13.0, *)) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillBecomeInactive:) name:UISceneWillDeactivateNotification object:nil]; } -#endif // defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 @try { [self loadFromCachePath:cachePath]; @@ -209,4 +207,4 @@ - (BOOL)saveIntoCacheWithPath:(NSString *)cacheFilePath { } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Analytics/FIRIAMClearcutLogger.m b/FirebaseInAppMessaging/Sources/Analytics/FIRIAMClearcutLogger.m index ea00175ebd0..be16272c896 100644 --- a/FirebaseInAppMessaging/Sources/Analytics/FIRIAMClearcutLogger.m +++ b/FirebaseInAppMessaging/Sources/Analytics/FIRIAMClearcutLogger.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseCore/Extension/FirebaseCoreInternal.h" @@ -214,4 +214,4 @@ - (void)logAnalyticsEventForType:(FIRIAMAnalyticsLogEventType)eventType } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Analytics/FIRIAMClearcutUploader.m b/FirebaseInAppMessaging/Sources/Analytics/FIRIAMClearcutUploader.m index c520f21616a..f424f51f878 100644 --- a/FirebaseInAppMessaging/Sources/Analytics/FIRIAMClearcutUploader.m +++ b/FirebaseInAppMessaging/Sources/Analytics/FIRIAMClearcutUploader.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import #import @@ -102,14 +102,12 @@ - (instancetype)initWithRequestSender:(FIRIAMClearcutHttpRequestSender *)request selector:@selector(scheduleNextSendFromForeground:) name:UIApplicationWillEnterForegroundNotification object:nil]; -#if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 if (@available(iOS 13.0, tvOS 13.0, *)) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scheduleNextSendFromForeground:) name:UISceneWillEnterForegroundNotification object:nil]; } -#endif // defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 _userDefaults = userDefaults ? userDefaults : [GULUserDefaults standardUserDefaults]; // it would be 0 if it does not exist, which is equvilent to saying that // you can send now @@ -246,4 +244,4 @@ - (void)scheduleNextSend { @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Data/FIRIAMFetchResponseParser.m b/FirebaseInAppMessaging/Sources/Data/FIRIAMFetchResponseParser.m index 8a85321de6e..7becace2949 100644 --- a/FirebaseInAppMessaging/Sources/Data/FIRIAMFetchResponseParser.m +++ b/FirebaseInAppMessaging/Sources/Data/FIRIAMFetchResponseParser.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseCore/Extension/FirebaseCoreInternal.h" @@ -399,4 +399,4 @@ - (NSString *)sanitizedURLStringFromString:(NSString *)string { @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Data/FIRIAMMessageContentDataWithImageURL.m b/FirebaseInAppMessaging/Sources/Data/FIRIAMMessageContentDataWithImageURL.m index 60b0b78bbcc..abe867bf6d6 100644 --- a/FirebaseInAppMessaging/Sources/Data/FIRIAMMessageContentDataWithImageURL.m +++ b/FirebaseInAppMessaging/Sources/Data/FIRIAMMessageContentDataWithImageURL.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseCore/Extension/FirebaseCoreInternal.h" @@ -206,4 +206,4 @@ - (void)fetchImageFromURL:(NSURL *)imageURL @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Data/FIRIAMMessageDefinition.m b/FirebaseInAppMessaging/Sources/Data/FIRIAMMessageDefinition.m index fb564630bca..4d72b82ac20 100644 --- a/FirebaseInAppMessaging/Sources/Data/FIRIAMMessageDefinition.m +++ b/FirebaseInAppMessaging/Sources/Data/FIRIAMMessageDefinition.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseInAppMessaging/Sources/Private/Data/FIRIAMMessageDefinition.h" @@ -109,4 +109,4 @@ - (BOOL)messageHasStarted { } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Data/FIRIAMRenderingEffectSetting.m b/FirebaseInAppMessaging/Sources/Data/FIRIAMRenderingEffectSetting.m index eeefee2d24e..1530049c6ba 100644 --- a/FirebaseInAppMessaging/Sources/Data/FIRIAMRenderingEffectSetting.m +++ b/FirebaseInAppMessaging/Sources/Data/FIRIAMRenderingEffectSetting.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseInAppMessaging/Sources/Private/Data/FIRIAMRenderingEffectSetting.h" @@ -34,4 +34,4 @@ + (instancetype)getDefaultRenderingEffectSetting { } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/DefaultUI/Banner/FIRIAMBannerViewController.m b/FirebaseInAppMessaging/Sources/DefaultUI/Banner/FIRIAMBannerViewController.m index 08952e2321a..ad7a95252aa 100644 --- a/FirebaseInAppMessaging/Sources/DefaultUI/Banner/FIRIAMBannerViewController.m +++ b/FirebaseInAppMessaging/Sources/DefaultUI/Banner/FIRIAMBannerViewController.m @@ -161,18 +161,14 @@ - (void)viewDidLoad { // Calculate status bar height. CGFloat statusBarHeight = 0; -#if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 if (@available(iOS 13.0, tvOS 13.0, *)) { UIStatusBarManager *manager = [UIApplication sharedApplication].keyWindow.windowScene.statusBarManager; statusBarHeight = manager.statusBarFrame.size.height; } else { -#endif statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height; -#if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 } -#endif // Pin title label below status bar with cushion. [[self.titleLabel.topAnchor constraintEqualToAnchor:self.view.topAnchor diff --git a/FirebaseInAppMessaging/Sources/DefaultUI/FIRIAMBaseRenderingViewController.m b/FirebaseInAppMessaging/Sources/DefaultUI/FIRIAMBaseRenderingViewController.m index f05fe050e3d..460fe9f60a2 100644 --- a/FirebaseInAppMessaging/Sources/DefaultUI/FIRIAMBaseRenderingViewController.m +++ b/FirebaseInAppMessaging/Sources/DefaultUI/FIRIAMBaseRenderingViewController.m @@ -55,7 +55,6 @@ - (void)viewDidLoad { selector:@selector(appDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil]; -#if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 if (@available(iOS 13.0, tvOS 13.0, *)) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillBecomeInactive:) @@ -67,7 +66,6 @@ - (void)viewDidLoad { name:UISceneDidActivateNotification object:nil]; } -#endif // defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 self.aggregateImpressionTimeInSeconds = 0; } diff --git a/FirebaseInAppMessaging/Sources/DefaultUI/FIRIAMDefaultDisplayImpl.m b/FirebaseInAppMessaging/Sources/DefaultUI/FIRIAMDefaultDisplayImpl.m index ed724bfcfe3..5673e179fb8 100644 --- a/FirebaseInAppMessaging/Sources/DefaultUI/FIRIAMDefaultDisplayImpl.m +++ b/FirebaseInAppMessaging/Sources/DefaultUI/FIRIAMDefaultDisplayImpl.m @@ -64,19 +64,33 @@ + (NSBundle *)getViewResourceBundle { bundledResource = @"InAppMessagingDisplayResources"; #endif // SWIFT_PACKAGE + NSMutableArray *bundles = [NSMutableArray array]; + + // Resources may be in main bundle when statically linked. + NSBundle *mainBundle = [NSBundle mainBundle]; + if (mainBundle) { + [bundles addObject:mainBundle]; + } + // Resources may be in the bundle associated with this class when + // dynamically linked. + NSBundle *bundleForClass = [NSBundle bundleForClass:myClass]; + if (bundleForClass) { + [bundles addObject:bundleForClass]; + } + // When embedding static frameworks from the zip distribution, the Xcode + // will copy the resources into the framework's directory. + NSBundle *frameworkBundle = [NSBundle + bundleWithURL: + [NSBundle.mainBundle.bundleURL + URLByAppendingPathComponent:@"Frameworks/FirebaseInAppMessaging.framework"]]; + if (frameworkBundle) { + [bundles addObject:frameworkBundle]; + } + NSBundle *containingBundle; NSURL *bundleURL; // The containing bundle is different whether FIAM is statically or dynamically linked. - for (containingBundle in @[ - // Statically linked. - [NSBundle mainBundle], - // Dynamically linked. - [NSBundle bundleForClass:myClass], - // Embedded static framework (zip distribution). - [NSBundle bundleWithURL:[NSBundle.mainBundle.bundleURL - URLByAppendingPathComponent: - @"Frameworks/FirebaseInAppMessaging.framework"]] - ]) { + for (containingBundle in bundles) { bundleURL = [containingBundle URLForResource:bundledResource withExtension:@"bundle"]; if (bundleURL != nil) break; } diff --git a/FirebaseInAppMessaging/Sources/DefaultUI/FIRIAMRenderingWindowHelper.m b/FirebaseInAppMessaging/Sources/DefaultUI/FIRIAMRenderingWindowHelper.m index e920a32e63c..2d42847474b 100644 --- a/FirebaseInAppMessaging/Sources/DefaultUI/FIRIAMRenderingWindowHelper.m +++ b/FirebaseInAppMessaging/Sources/DefaultUI/FIRIAMRenderingWindowHelper.m @@ -28,15 +28,11 @@ + (UIWindow *)windowForBlockingView { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ -#if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 if (@available(iOS 13.0, tvOS 13.0, *)) { UIWindowForModal = [[self class] iOS13PlusWindow]; } else { -#endif // defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 UIWindowForModal = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; -#if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 } -#endif // defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 UIWindowForModal.windowLevel = UIWindowLevelNormal; }); return UIWindowForModal; @@ -47,23 +43,18 @@ + (UIWindow *)windowForNonBlockingView { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ -#if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 if (@available(iOS 13.0, tvOS 13.0, *)) { UIWindowForBanner = [[self class] iOS13PlusBannerWindow]; } else { -#endif // defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 UIWindowForBanner = [[FIRIAMBannerViewUIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; -#if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 } -#endif UIWindowForBanner.windowLevel = UIWindowLevelNormal; }); return UIWindowForBanner; } -#if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 + (UIWindow *)iOS13PlusWindow API_AVAILABLE(ios(13.0)) { UIWindowScene *foregroundedScene = [[UIApplication sharedApplication] fir_foregroundWindowScene]; if (foregroundedScene.delegate) { @@ -82,7 +73,6 @@ + (FIRIAMBannerViewUIWindow *)iOS13PlusBannerWindow API_AVAILABLE(ios(13.0)) { } } -#endif @end #endif // TARGET_OS_IOS diff --git a/FirebaseInAppMessaging/Sources/DefaultUI/ImageOnly/FIRIAMImageOnlyViewController.m b/FirebaseInAppMessaging/Sources/DefaultUI/ImageOnly/FIRIAMImageOnlyViewController.m index ffc37a408ec..6f57f6e0d0a 100644 --- a/FirebaseInAppMessaging/Sources/DefaultUI/ImageOnly/FIRIAMImageOnlyViewController.m +++ b/FirebaseInAppMessaging/Sources/DefaultUI/ImageOnly/FIRIAMImageOnlyViewController.m @@ -124,11 +124,7 @@ - (void)viewDidLayoutSubviews { CGFloat maxImageViewHeight = self.view.window.frame.size.height - minimalMargine * 2; // Factor in space for the top notch on iPhone X*. -#if defined(__IPHONE_11_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 - if (@available(iOS 11.0, *)) { - maxImageViewHeight -= self.view.safeAreaInsets.top; - } -#endif // defined(__IPHONE_11_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + maxImageViewHeight -= self.view.safeAreaInsets.top; CGFloat adjustedImageViewHeight = self.imageOriginalSize.height; CGFloat adjustedImageViewWidth = self.imageOriginalSize.width; diff --git a/FirebaseInAppMessaging/Sources/DefaultUI/Modal/FIRIAMModalViewController.m b/FirebaseInAppMessaging/Sources/DefaultUI/Modal/FIRIAMModalViewController.m index e605e239cc6..efad4f62396 100644 --- a/FirebaseInAppMessaging/Sources/DefaultUI/Modal/FIRIAMModalViewController.m +++ b/FirebaseInAppMessaging/Sources/DefaultUI/Modal/FIRIAMModalViewController.m @@ -288,11 +288,7 @@ - (void)layoutFineTuneInPortraitMode { TopBottomPaddingAroundMsgCard * 2; // Factor in space for the top notch on iPhone X*. -#if defined(__IPHONE_11_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 - if (@available(iOS 11.0, *)) { - heightCalcReference -= self.view.safeAreaInsets.top; - } -#endif // defined(__IPHONE_11_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + heightCalcReference -= self.view.safeAreaInsets.top; } FIRLogDebug(kFIRLoggerInAppMessagingDisplay, @"I-FID300004", diff --git a/FirebaseInAppMessaging/Sources/DisplayTrigger/FIRIAMDisplayTriggerDefinition.m b/FirebaseInAppMessaging/Sources/DisplayTrigger/FIRIAMDisplayTriggerDefinition.m index 766ec4cc4cf..9de6b8a804b 100644 --- a/FirebaseInAppMessaging/Sources/DisplayTrigger/FIRIAMDisplayTriggerDefinition.m +++ b/FirebaseInAppMessaging/Sources/DisplayTrigger/FIRIAMDisplayTriggerDefinition.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseInAppMessaging/Sources/Private/DisplayTrigger/FIRIAMDisplayTriggerDefinition.h" @@ -43,4 +43,4 @@ - (instancetype)initWithFirebaseAnalyticEvent:(NSString *)title { } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/FIRCore+InAppMessaging.m b/FirebaseInAppMessaging/Sources/FIRCore+InAppMessaging.m index 58c3a741cc3..db5ae0816e0 100644 --- a/FirebaseInAppMessaging/Sources/FIRCore+InAppMessaging.m +++ b/FirebaseInAppMessaging/Sources/FIRCore+InAppMessaging.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import #import "FirebaseInAppMessaging/Sources/FIRCore+InAppMessaging.h" @@ -23,4 +23,4 @@ NSString *const kFirebaseInAppMessagingErrorDomain = @"com.firebase.inappmessaging"; FIRLoggerService kFIRLoggerInAppMessaging = @"[FirebaseInAppMessaging]"; -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/FIRInAppMessaging.m b/FirebaseInAppMessaging/Sources/FIRInAppMessaging.m index 3f9595582ac..8b65d0a4efa 100644 --- a/FirebaseInAppMessaging/Sources/FIRInAppMessaging.m +++ b/FirebaseInAppMessaging/Sources/FIRInAppMessaging.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseInAppMessaging/Sources/Public/FirebaseInAppMessaging/FIRInAppMessaging.h" @@ -145,4 +145,4 @@ - (void)triggerEvent:(NSString *)eventName { @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Flows/FIRIAMActivityLogger.m b/FirebaseInAppMessaging/Sources/Flows/FIRIAMActivityLogger.m index 20862570659..dac6a28f829 100644 --- a/FirebaseInAppMessaging/Sources/Flows/FIRIAMActivityLogger.m +++ b/FirebaseInAppMessaging/Sources/Flows/FIRIAMActivityLogger.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import @@ -113,14 +113,12 @@ - (instancetype)initWithMaxCountBeforeReduce:(NSInteger)maxBeforeReduce selector:@selector(appWillBecomeInactive:) name:UIApplicationWillResignActiveNotification object:nil]; -#if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 if (@available(iOS 13.0, tvOS 13.0, *)) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillBecomeInactive:) name:UISceneWillDeactivateNotification object:nil]; } -#endif // defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 if (loadFromCache) { @try { [self loadFromCachePath:nil]; @@ -245,4 +243,4 @@ - (void)addLogRecord:(FIRIAMActivityRecord *)newRecord { } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Flows/FIRIAMBookKeeper.m b/FirebaseInAppMessaging/Sources/Flows/FIRIAMBookKeeper.m index db85d8723c5..5e17566b4cc 100644 --- a/FirebaseInAppMessaging/Sources/Flows/FIRIAMBookKeeper.m +++ b/FirebaseInAppMessaging/Sources/Flows/FIRIAMBookKeeper.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import @@ -264,4 +264,4 @@ - (void)cleanupFetchRecords { } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Flows/FIRIAMClientInfoFetcher.m b/FirebaseInAppMessaging/Sources/Flows/FIRIAMClientInfoFetcher.m index 7d32c188a02..f9363e438ca 100644 --- a/FirebaseInAppMessaging/Sources/Flows/FIRIAMClientInfoFetcher.m +++ b/FirebaseInAppMessaging/Sources/Flows/FIRIAMClientInfoFetcher.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseCore/Extension/FirebaseCoreInternal.h" #import "FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h" @@ -133,4 +133,4 @@ - (NSString *)getIAMSDKVersion { } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Flows/FIRIAMDisplayCheckOnAnalyticEventsFlow.m b/FirebaseInAppMessaging/Sources/Flows/FIRIAMDisplayCheckOnAnalyticEventsFlow.m index 63e7651dc96..4e3a1491919 100644 --- a/FirebaseInAppMessaging/Sources/Flows/FIRIAMDisplayCheckOnAnalyticEventsFlow.m +++ b/FirebaseInAppMessaging/Sources/Flows/FIRIAMDisplayCheckOnAnalyticEventsFlow.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseCore/Extension/FirebaseCoreInternal.h" #import "Interop/Analytics/Public/FIRAnalyticsInterop.h" @@ -68,4 +68,4 @@ - (void)stop { @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Flows/FIRIAMDisplayCheckOnAppForegroundFlow.m b/FirebaseInAppMessaging/Sources/Flows/FIRIAMDisplayCheckOnAppForegroundFlow.m index 078b7d39706..27fc9492ba1 100644 --- a/FirebaseInAppMessaging/Sources/Flows/FIRIAMDisplayCheckOnAppForegroundFlow.m +++ b/FirebaseInAppMessaging/Sources/Flows/FIRIAMDisplayCheckOnAppForegroundFlow.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseCore/Extension/FirebaseCoreInternal.h" @@ -33,7 +33,6 @@ - (void)start { selector:@selector(checkAndDisplayNextAppForegroundMessageFromForeground:) name:UIApplicationWillEnterForegroundNotification object:nil]; -#if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 if (@available(iOS 13.0, tvOS 13.0, *)) { [[NSNotificationCenter defaultCenter] addObserver:self @@ -41,7 +40,6 @@ - (void)start { name:UISceneWillEnterForegroundNotification object:nil]; } -#endif // defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 } - (void)checkAndDisplayNextAppForegroundMessageFromForeground:(NSNotification *)notification { @@ -67,4 +65,4 @@ - (void)dealloc { } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Flows/FIRIAMDisplayCheckOnFetchDoneNotificationFlow.m b/FirebaseInAppMessaging/Sources/Flows/FIRIAMDisplayCheckOnFetchDoneNotificationFlow.m index 45d4b39f563..6983910c051 100644 --- a/FirebaseInAppMessaging/Sources/Flows/FIRIAMDisplayCheckOnFetchDoneNotificationFlow.m +++ b/FirebaseInAppMessaging/Sources/Flows/FIRIAMDisplayCheckOnFetchDoneNotificationFlow.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseCore/Extension/FirebaseCoreInternal.h" @@ -64,4 +64,4 @@ - (void)dealloc { } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Flows/FIRIAMDisplayCheckTriggerFlow.m b/FirebaseInAppMessaging/Sources/Flows/FIRIAMDisplayCheckTriggerFlow.m index b7f3137ad18..6ab0c90c41f 100644 --- a/FirebaseInAppMessaging/Sources/Flows/FIRIAMDisplayCheckTriggerFlow.m +++ b/FirebaseInAppMessaging/Sources/Flows/FIRIAMDisplayCheckTriggerFlow.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseInAppMessaging/Sources/Private/Flows/FIRIAMDisplayCheckTriggerFlow.h" @@ -34,4 +34,4 @@ - (void)stop { } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Flows/FIRIAMDisplayExecutor.m b/FirebaseInAppMessaging/Sources/Flows/FIRIAMDisplayExecutor.m index c4ec0def848..c7b10afe459 100644 --- a/FirebaseInAppMessaging/Sources/Flows/FIRIAMDisplayExecutor.m +++ b/FirebaseInAppMessaging/Sources/Flows/FIRIAMDisplayExecutor.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import #import "FirebaseCore/Extension/FirebaseCoreInternal.h" @@ -355,7 +355,6 @@ - (void)displayMessageLoadError:(NSError *)error { [alert addAction:defaultAction]; dispatch_async(dispatch_get_main_queue(), ^{ -#if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 if (@available(iOS 13.0, tvOS 13.0, *)) { UIWindowScene *foregroundedScene = [[UIApplication sharedApplication] fir_foregroundWindowScene]; @@ -364,10 +363,11 @@ - (void)displayMessageLoadError:(NSError *)error { return; } self.alertWindow = [[UIWindow alloc] initWithWindowScene:foregroundedScene]; - } -#else // defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 - self.alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; +#if TARGET_OS_IOS || TARGET_OS_TV + } else { + self.alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; #endif + } UIViewController *alertViewController = [[UIViewController alloc] init]; self.alertWindow.rootViewController = alertViewController; self.alertWindow.hidden = NO; @@ -778,4 +778,4 @@ - (void)checkAndDisplayNextAppForegroundMessage { } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Flows/FIRIAMFetchFlow.m b/FirebaseInAppMessaging/Sources/Flows/FIRIAMFetchFlow.m index 38f8c181ffe..890fece4d57 100644 --- a/FirebaseInAppMessaging/Sources/Flows/FIRIAMFetchFlow.m +++ b/FirebaseInAppMessaging/Sources/Flows/FIRIAMFetchFlow.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseCore/Extension/FirebaseCoreInternal.h" @@ -267,4 +267,4 @@ - (void)checkForAppLaunchMessage { } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Flows/FIRIAMFetchOnAppForegroundFlow.m b/FirebaseInAppMessaging/Sources/Flows/FIRIAMFetchOnAppForegroundFlow.m index 0a217b1faa6..946a9ec56b2 100644 --- a/FirebaseInAppMessaging/Sources/Flows/FIRIAMFetchOnAppForegroundFlow.m +++ b/FirebaseInAppMessaging/Sources/Flows/FIRIAMFetchOnAppForegroundFlow.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseCore/Extension/FirebaseCoreInternal.h" @@ -29,14 +29,12 @@ - (void)start { selector:@selector(appWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil]; -#if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 if (@available(iOS 13.0, tvOS 13.0, *)) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillEnterForeground:) name:UISceneWillEnterForegroundNotification object:nil]; } -#endif // defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 } - (void)appWillEnterForeground:(NSNotification *)notification { @@ -61,4 +59,4 @@ - (void)dealloc { } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Flows/FIRIAMMessageClientCache.m b/FirebaseInAppMessaging/Sources/Flows/FIRIAMMessageClientCache.m index 37f24531edd..844272ceaa0 100644 --- a/FirebaseInAppMessaging/Sources/Flows/FIRIAMMessageClientCache.m +++ b/FirebaseInAppMessaging/Sources/Flows/FIRIAMMessageClientCache.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseCore/Extension/FirebaseCoreInternal.h" @@ -238,4 +238,4 @@ - (void)loadMessageDataFromServerFetchStorage:(FIRIAMServerMsgFetchStorage *)fet } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Flows/FIRIAMMsgFetcherUsingRestful.m b/FirebaseInAppMessaging/Sources/Flows/FIRIAMMsgFetcherUsingRestful.m index 772148b6018..77053791922 100644 --- a/FirebaseInAppMessaging/Sources/Flows/FIRIAMMsgFetcherUsingRestful.m +++ b/FirebaseInAppMessaging/Sources/Flows/FIRIAMMsgFetcherUsingRestful.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseCore/Extension/FirebaseCoreInternal.h" @@ -277,4 +277,4 @@ - (void)fetchMessagesWithImpressionList:(NSArray *)imp } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Flows/FIRIAMServerMsgFetchStorage.m b/FirebaseInAppMessaging/Sources/Flows/FIRIAMServerMsgFetchStorage.m index 713550f8685..dfe42933697 100644 --- a/FirebaseInAppMessaging/Sources/Flows/FIRIAMServerMsgFetchStorage.m +++ b/FirebaseInAppMessaging/Sources/Flows/FIRIAMServerMsgFetchStorage.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseCore/Extension/FirebaseCoreInternal.h" @@ -66,4 +66,4 @@ - (void)readResponseDictionary:(void (^)(NSDictionary *response, BOOL success))c } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/RenderingObjects/FIRInAppMessagingRenderingDataClasses.m b/FirebaseInAppMessaging/Sources/RenderingObjects/FIRInAppMessagingRenderingDataClasses.m index 36d81939500..663c72b8438 100644 --- a/FirebaseInAppMessaging/Sources/RenderingObjects/FIRInAppMessagingRenderingDataClasses.m +++ b/FirebaseInAppMessaging/Sources/RenderingObjects/FIRInAppMessagingRenderingDataClasses.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import @@ -371,4 +371,4 @@ - (instancetype)initWithActionText:(nullable NSString *)actionText @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Runtime/FIRIAMActionURLFollower.m b/FirebaseInAppMessaging/Sources/Runtime/FIRIAMActionURLFollower.m index cbcae06e2cb..f16936f9423 100644 --- a/FirebaseInAppMessaging/Sources/Runtime/FIRIAMActionURLFollower.m +++ b/FirebaseInAppMessaging/Sources/Runtime/FIRIAMActionURLFollower.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import #import @@ -227,4 +227,4 @@ + (BOOL)isHttpOrHttpsScheme:(NSURL *)url { } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Runtime/FIRIAMRuntimeManager.m b/FirebaseInAppMessaging/Sources/Runtime/FIRIAMRuntimeManager.m index 499b6fddc9b..b3fb094c67b 100644 --- a/FirebaseInAppMessaging/Sources/Runtime/FIRIAMRuntimeManager.m +++ b/FirebaseInAppMessaging/Sources/Runtime/FIRIAMRuntimeManager.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import @@ -446,4 +446,4 @@ - (void)internalStartRuntimeWithSDKSettings:(FIRIAMSDKSettings *)settings { } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Runtime/FIRIAMSDKModeManager.m b/FirebaseInAppMessaging/Sources/Runtime/FIRIAMSDKModeManager.m index 6aa77c29f8d..39d51af13ca 100644 --- a/FirebaseInAppMessaging/Sources/Runtime/FIRIAMSDKModeManager.m +++ b/FirebaseInAppMessaging/Sources/Runtime/FIRIAMSDKModeManager.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import @@ -117,4 +117,4 @@ - (FIRIAMSDKMode)currentMode { } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Runtime/FIRIAMSDKSettings.m b/FirebaseInAppMessaging/Sources/Runtime/FIRIAMSDKSettings.m index eccb73beaea..d2d05f6267b 100644 --- a/FirebaseInAppMessaging/Sources/Runtime/FIRIAMSDKSettings.m +++ b/FirebaseInAppMessaging/Sources/Runtime/FIRIAMSDKSettings.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseInAppMessaging/Sources/Private/Runtime/FIRIAMSDKSettings.h" @@ -37,4 +37,4 @@ - (NSString *)description { } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Runtime/FIRInAppMessaging+Bootstrap.m b/FirebaseInAppMessaging/Sources/Runtime/FIRInAppMessaging+Bootstrap.m index 1d1c773bf54..800c70787f6 100644 --- a/FirebaseInAppMessaging/Sources/Runtime/FIRInAppMessaging+Bootstrap.m +++ b/FirebaseInAppMessaging/Sources/Runtime/FIRInAppMessaging+Bootstrap.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseInAppMessaging/Sources/Private/Runtime/FIRInAppMessaging+Bootstrap.h" @@ -136,4 +136,4 @@ + (void)exitAppWithFatalError:(NSError *)error { @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Util/FIRIAMElapsedTimeTracker.m b/FirebaseInAppMessaging/Sources/Util/FIRIAMElapsedTimeTracker.m index b299f17b3c7..d60a8e48c58 100644 --- a/FirebaseInAppMessaging/Sources/Util/FIRIAMElapsedTimeTracker.m +++ b/FirebaseInAppMessaging/Sources/Util/FIRIAMElapsedTimeTracker.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseInAppMessaging/Sources/Util/FIRIAMElapsedTimeTracker.h" @interface FIRIAMElapsedTimeTracker () @@ -58,4 +58,4 @@ - (instancetype)initWithTimeFetcher:(id)timeFetcher { } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Util/FIRIAMTimeFetcher.m b/FirebaseInAppMessaging/Sources/Util/FIRIAMTimeFetcher.m index c94798d87dd..1c74a24e264 100644 --- a/FirebaseInAppMessaging/Sources/Util/FIRIAMTimeFetcher.m +++ b/FirebaseInAppMessaging/Sources/Util/FIRIAMTimeFetcher.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseInAppMessaging/Sources/Private/Util/FIRIAMTimeFetcher.h" @@ -25,4 +25,4 @@ - (NSTimeInterval)currentTimestampInSeconds { } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Util/NSString+FIRInterlaceStrings.m b/FirebaseInAppMessaging/Sources/Util/NSString+FIRInterlaceStrings.m index ed2671daa9a..787da932356 100644 --- a/FirebaseInAppMessaging/Sources/Util/NSString+FIRInterlaceStrings.m +++ b/FirebaseInAppMessaging/Sources/Util/NSString+FIRInterlaceStrings.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseInAppMessaging/Sources/Private/Util/NSString+FIRInterlaceStrings.h" @@ -44,4 +44,4 @@ + (NSString *)fir_interlaceString:(NSString *)stringOne withString:(NSString *)s @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Util/UIApplication+FIRForegroundWindowScene.m b/FirebaseInAppMessaging/Sources/Util/UIApplication+FIRForegroundWindowScene.m index ad0a5ec22c4..1658ad41c74 100644 --- a/FirebaseInAppMessaging/Sources/Util/UIApplication+FIRForegroundWindowScene.m +++ b/FirebaseInAppMessaging/Sources/Util/UIApplication+FIRForegroundWindowScene.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseInAppMessaging/Sources/Private/Util/UIApplication+FIRForegroundWindowScene.h" @@ -37,4 +37,4 @@ - (nullable UIWindowScene *)fir_foregroundWindowScene { @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Sources/Util/UIColor+FIRIAMHexString.m b/FirebaseInAppMessaging/Sources/Util/UIColor+FIRIAMHexString.m index 3374623070a..34c9e220e0e 100644 --- a/FirebaseInAppMessaging/Sources/Util/UIColor+FIRIAMHexString.m +++ b/FirebaseInAppMessaging/Sources/Util/UIColor+FIRIAMHexString.m @@ -15,7 +15,7 @@ */ #import -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION #import "FirebaseInAppMessaging/Sources/Util/UIColor+FIRIAMHexString.h" @@ -41,4 +41,4 @@ + (UIColor *)firiam_colorWithHexString:(nullable NSString *)hexString { } @end -#endif // TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION diff --git a/FirebaseInAppMessaging/Swift/Source/SwiftUIPreviewHelpers.swift b/FirebaseInAppMessaging/Swift/Source/SwiftUIPreviewHelpers.swift index 3752429b6b0..9b64490fb47 100644 --- a/FirebaseInAppMessaging/Swift/Source/SwiftUIPreviewHelpers.swift +++ b/FirebaseInAppMessaging/Swift/Source/SwiftUIPreviewHelpers.swift @@ -96,7 +96,7 @@ public enum InAppMessagingPreviewHelpers { } var actionButton: InAppMessagingActionButton? - if let buttonText = buttonText, + if let buttonText, let buttonTextColor = buttonTextColor, let buttonBackgroundColor = buttonBackgroundColor { actionButton = InAppMessagingActionButton(buttonText: buttonText, diff --git a/FirebaseInstallations.podspec b/FirebaseInstallations.podspec index 1b13896d9c2..2d136bace4b 100644 --- a/FirebaseInstallations.podspec +++ b/FirebaseInstallations.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseInstallations' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Firebase Installations' s.description = <<-DESC diff --git a/FirebaseInstallations/Source/Tests/Unit/Swift/InstallationsAPITests.swift b/FirebaseInstallations/Source/Tests/Unit/Swift/InstallationsAPITests.swift index 51d1ae8f713..01ace9a2afb 100644 --- a/FirebaseInstallations/Source/Tests/Unit/Swift/InstallationsAPITests.swift +++ b/FirebaseInstallations/Source/Tests/Unit/Swift/InstallationsAPITests.swift @@ -131,7 +131,7 @@ final class InstallationsAPITests { // MARK: - InstallationsAuthTokenResult Installations.installations().authToken { result, _ in - if let result = result { + if let result { _ = result.expirationDate _ = result.authToken } @@ -140,7 +140,7 @@ final class InstallationsAPITests { // MARK: - InstallationsErrorCode Installations.installations().authToken { _, error in - if let error = error { + if let error { // Old error handling. switch (error as NSError).code { case Int(InstallationsErrorCode.unknown.rawValue): diff --git a/FirebaseMLModelDownloader.podspec b/FirebaseMLModelDownloader.podspec index 16724bb2972..94a17627f44 100644 --- a/FirebaseMLModelDownloader.podspec +++ b/FirebaseMLModelDownloader.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseMLModelDownloader' - s.version = '10.25.0-beta' + s.version = '10.27.0-beta' s.summary = 'Firebase ML Model Downloader' s.description = <<-DESC diff --git a/FirebaseMLModelDownloader/Sources/ModelDownloader.swift b/FirebaseMLModelDownloader/Sources/ModelDownloader.swift index ba5e047757b..fb99d831209 100644 --- a/FirebaseMLModelDownloader/Sources/ModelDownloader.swift +++ b/FirebaseMLModelDownloader/Sources/ModelDownloader.swift @@ -438,7 +438,7 @@ extension ModelDownloader { case let .modelInfo(remoteModelInfo): // Progress handler for model file download. let taskProgressHandler: ModelDownloadTask.ProgressHandler = { progress in - if let progressHandler = progressHandler { + if let progressHandler { self.asyncOnMainQueue(progressHandler(progress)) } } diff --git a/FirebaseMLModelDownloader/Sources/ModelFileManager.swift b/FirebaseMLModelDownloader/Sources/ModelFileManager.swift index e1f24e47db6..8e9acdef84a 100644 --- a/FirebaseMLModelDownloader/Sources/ModelFileManager.swift +++ b/FirebaseMLModelDownloader/Sources/ModelFileManager.swift @@ -195,7 +195,7 @@ extension ModelFileManager { } static let availableStorage = { (error: String?) -> String in - if let error = error { + if let error { return "Failed to check storage capacity on device: \(error)" } else { return "Failed to check storage capacity on device." diff --git a/FirebaseMLModelDownloader/Sources/ModelInfoRetriever.swift b/FirebaseMLModelDownloader/Sources/ModelInfoRetriever.swift index 20a8c7ef7dd..afaa58e7a7e 100644 --- a/FirebaseMLModelDownloader/Sources/ModelInfoRetriever.swift +++ b/FirebaseMLModelDownloader/Sources/ModelInfoRetriever.swift @@ -500,9 +500,9 @@ extension ModelInfoRetriever { request.setValue(bundleID, forHTTPHeaderField: ModelInfoRetriever.bundleIDHTTPHeader) request.setValue(token, forHTTPHeaderField: ModelInfoRetriever.fisTokenHTTPHeader) // Get model hash if local model info is available on device. - if let modelInfo = localModelInfo { + if let localModelInfo { request.setValue( - modelInfo.modelHash, + localModelInfo.modelHash, forHTTPHeaderField: ModelInfoRetriever.hashMatchHTTPHeader ) } @@ -511,7 +511,7 @@ extension ModelInfoRetriever { /// Parse error message from server response. private func getErrorFromResponse(_ data: Data?) -> String? { - if let data = data, + if let data, let responseJSON = try? JSONSerialization .jsonObject(with: data, options: []) as? [String: Any], let error = responseJSON["error"] as? [String: Any], diff --git a/FirebaseMLModelDownloader/Sources/TelemetryLogger.swift b/FirebaseMLModelDownloader/Sources/TelemetryLogger.swift index 23386d06bb1..79b91c8e2d2 100644 --- a/FirebaseMLModelDownloader/Sources/TelemetryLogger.swift +++ b/FirebaseMLModelDownloader/Sources/TelemetryLogger.swift @@ -63,14 +63,14 @@ extension ModelDownloadLogEvent { downloadFailureStatus: Int64? = 0, modelOptions: ModelOptions) { downloadStatus = status self.errorCode = errorCode - if let roughDuration = roughDownloadDuration { - roughDownloadDurationMs = roughDuration + if let roughDownloadDuration { + roughDownloadDurationMs = roughDownloadDuration } - if let exactDuration = exactDownloadDuration { - exactDownloadDurationMs = exactDuration + if let exactDownloadDuration { + exactDownloadDurationMs = exactDownloadDuration } - if let failureStatus = downloadFailureStatus { - self.downloadFailureStatus = failureStatus + if let downloadFailureStatus { + self.downloadFailureStatus = downloadFailureStatus } options = modelOptions } diff --git a/FirebaseMessaging.podspec b/FirebaseMessaging.podspec index 8791a5509ee..a65bafc51db 100644 --- a/FirebaseMessaging.podspec +++ b/FirebaseMessaging.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseMessaging' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Firebase Messaging' s.description = <<-DESC diff --git a/FirebaseMessaging/Apps/AdvancedSample/NotificationServiceExtension/NotificationService.swift b/FirebaseMessaging/Apps/AdvancedSample/NotificationServiceExtension/NotificationService.swift index bf48feb3b29..a6bc72e483b 100644 --- a/FirebaseMessaging/Apps/AdvancedSample/NotificationServiceExtension/NotificationService.swift +++ b/FirebaseMessaging/Apps/AdvancedSample/NotificationServiceExtension/NotificationService.swift @@ -25,7 +25,7 @@ class NotificationService: UNNotificationServiceExtension { self.contentHandler = contentHandler bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) - if let bestAttemptContent = bestAttemptContent { + if let bestAttemptContent { // Modify the notification content here... bestAttemptContent.title = "\(bestAttemptContent.title) 👩🏻‍💻" @@ -43,7 +43,7 @@ class NotificationService: UNNotificationServiceExtension { // Called just before the extension will be terminated by the system. // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the // original push payload will be used. - if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { + if let contentHandler, let bestAttemptContent { contentHandler(bestAttemptContent) } } diff --git a/FirebaseMessaging/CHANGELOG.md b/FirebaseMessaging/CHANGELOG.md index 8191c09c6b3..c718a756697 100644 --- a/FirebaseMessaging/CHANGELOG.md +++ b/FirebaseMessaging/CHANGELOG.md @@ -1,3 +1,7 @@ +# 10.27.0 +- [fixed] Fixed bug preventing Messaging from working with a custom sqlite3 + dependency (#12900). + # 10.23.0 - [fixed] [CocoaPods] Fix "no rule" warning when running `pod install`. (#12511) diff --git a/FirebaseMessaging/Sources/FIRMessaging.m b/FirebaseMessaging/Sources/FIRMessaging.m index d28db581f2d..98f5e7dcb68 100644 --- a/FirebaseMessaging/Sources/FIRMessaging.m +++ b/FirebaseMessaging/Sources/FIRMessaging.m @@ -49,13 +49,8 @@ static NSString *const kFIRMessagingMessageViaAPNSRootKey = @"aps"; static NSString *const kFIRMessagingReachabilityHostname = @"www.google.com"; -#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 const NSNotificationName FIRMessagingRegistrationTokenRefreshedNotification = @"com.firebase.messaging.notif.fcm-token-refreshed"; -#else -NSString *const FIRMessagingRegistrationTokenRefreshedNotification = - @"com.firebase.messaging.notif.fcm-token-refreshed"; -#endif // defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 NSString *const kFIRMessagingUserDefaultsKeyAutoInitEnabled = @"com.firebase.messaging.auto-init.enabled"; // Auto Init Enabled key stored in NSUserDefaults diff --git a/FirebaseMessaging/Sources/FIRMessagingContextManagerService.m b/FirebaseMessaging/Sources/FIRMessagingContextManagerService.m index 741a62e65a9..b86e84cb3e6 100644 --- a/FirebaseMessaging/Sources/FIRMessagingContextManagerService.m +++ b/FirebaseMessaging/Sources/FIRMessagingContextManagerService.m @@ -13,11 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 || \ - __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_14 || __TV_OS_VERSION_MAX_ALLOWED >= __TV_10_0 || \ - __WATCH_OS_VERSION_MAX_ALLOWED >= __WATCHOS_3_0 || TARGET_OS_MACCATALYST + #import -#endif #import "FirebaseMessaging/Sources/FIRMessagingContextManagerService.h" diff --git a/FirebaseMessaging/Sources/FIRMessagingRmqManager.m b/FirebaseMessaging/Sources/FIRMessagingRmqManager.m index ad66dcea2ce..fbc9dd04dc4 100644 --- a/FirebaseMessaging/Sources/FIRMessagingRmqManager.m +++ b/FirebaseMessaging/Sources/FIRMessagingRmqManager.m @@ -490,9 +490,11 @@ - (void)openDatabase { BOOL didOpenDatabase = YES; if (![fileManager fileExistsAtPath:path]) { // We've to separate between different versions here because of backwards compatbility issues. - int result = sqlite3_open_v2( - [path UTF8String], &self -> _database, - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FILEPROTECTION_NONE, NULL); + int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; +#ifdef SQLITE_OPEN_FILEPROTECTION_NONE + flags |= SQLITE_OPEN_FILEPROTECTION_NONE; +#endif + int result = sqlite3_open_v2([path UTF8String], &self -> _database, flags, NULL); if (result != SQLITE_OK) { NSString *errorString = FIRMessagingStringFromSQLiteResult(result); NSString *errorMessage = [NSString @@ -509,9 +511,11 @@ - (void)openDatabase { [self createTableWithName:kTableS2DRmqIds command:kCreateTableS2DRmqIds]; } else { // Calling sqlite3_open should create the database, since the file doesn't exist. - int result = sqlite3_open_v2( - [path UTF8String], &self -> _database, - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FILEPROTECTION_NONE, NULL); + int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; +#ifdef SQLITE_OPEN_FILEPROTECTION_NONE + flags |= SQLITE_OPEN_FILEPROTECTION_NONE; +#endif + int result = sqlite3_open_v2([path UTF8String], &self -> _database, flags, NULL); if (result != SQLITE_OK) { NSString *errorString = FIRMessagingStringFromSQLiteResult(result); NSString *errorMessage = diff --git a/FirebaseMessaging/Sources/FIRMessagingUtilities.m b/FirebaseMessaging/Sources/FIRMessagingUtilities.m index 713febdb833..2d9bddb5187 100644 --- a/FirebaseMessaging/Sources/FIRMessagingUtilities.m +++ b/FirebaseMessaging/Sources/FIRMessagingUtilities.m @@ -311,8 +311,7 @@ BOOL FIRMessagingIsProductionApp(void) { #if TARGET_OS_OSX || TARGET_OS_MACCATALYST NSString *path = [[[[NSBundle mainBundle] resourcePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"embedded.provisionprofile"]; -#elif TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH || \ - (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#elif TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH || TARGET_OS_VISION NSString *path = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"embedded.mobileprovision"]; #endif diff --git a/FirebaseMessaging/Sources/Token/FIRMessagingAuthKeychain.m b/FirebaseMessaging/Sources/Token/FIRMessagingAuthKeychain.m index 51e2f955334..544d1718d80 100644 --- a/FirebaseMessaging/Sources/Token/FIRMessagingAuthKeychain.m +++ b/FirebaseMessaging/Sources/Token/FIRMessagingAuthKeychain.m @@ -92,7 +92,7 @@ - (NSMutableDictionary *)keychainQueryForService:(NSString *)service account:(NS NSMutableDictionary *keychainQuery = [self keychainQueryForService:service account:account]; NSMutableArray *results; keychainQuery[(__bridge id)kSecReturnData] = (__bridge id)kCFBooleanTrue; -#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION keychainQuery[(__bridge id)kSecReturnAttributes] = (__bridge id)kCFBooleanTrue; keychainQuery[(__bridge id)kSecMatchLimit] = (__bridge id)kSecMatchLimitAll; // FIRMessagingKeychain should only take a query and return a result, will handle the query here. diff --git a/FirebaseMessaging/Tests/UnitTests/FIRMessagingContextManagerServiceTest.m b/FirebaseMessaging/Tests/UnitTests/FIRMessagingContextManagerServiceTest.m index dd03e1bd4e4..1339a690465 100644 --- a/FirebaseMessaging/Tests/UnitTests/FIRMessagingContextManagerServiceTest.m +++ b/FirebaseMessaging/Tests/UnitTests/FIRMessagingContextManagerServiceTest.m @@ -13,12 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 || \ - __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_14 || __TV_OS_VERSION_MAX_ALLOWED >= __TV_10_0 || \ - __WATCH_OS_VERSION_MAX_ALLOWED >= __WATCHOS_3_0 || TARGET_OS_MACCATALYST -#import -#endif + #import +#import #import #import "FirebaseMessaging/Sources/FIRMessagingContextManagerService.h" diff --git a/FirebaseMessaging/Tests/UnitTests/FIRMessagingRemoteNotificationsProxyTest.m b/FirebaseMessaging/Tests/UnitTests/FIRMessagingRemoteNotificationsProxyTest.m index 9fadff6f46b..d3bbdc3ead3 100644 --- a/FirebaseMessaging/Tests/UnitTests/FIRMessagingRemoteNotificationsProxyTest.m +++ b/FirebaseMessaging/Tests/UnitTests/FIRMessagingRemoteNotificationsProxyTest.m @@ -14,11 +14,8 @@ * limitations under the License. */ -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 || \ - __TV_OS_VERSION_MAX_ALLOWED >= __TV_10_0 || __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_14 -#import -#endif #import +#import #import #import @@ -95,8 +92,6 @@ - (void)application:(GULApplication *)application @end -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 || \ - __TV_OS_VERSION_MAX_ALLOWED >= __TV_10_0 || __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_14 #pragma mark - Incompete UNUserNotificationCenterDelegate @interface IncompleteUserNotificationCenterDelegate : NSObject @end @@ -127,8 +122,6 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center #endif @end -#endif - @interface GULAppDelegateSwizzler (FIRMessagingRemoteNotificationsProxyTest) + (void)resetProxyOriginalDelegateOnceToken; @end diff --git a/FirebaseMessaging/Tests/UnitTestsSwift/FIRMessagingAPITest.swift b/FirebaseMessaging/Tests/UnitTestsSwift/FIRMessagingAPITest.swift index f48e663bd7f..66441a37ae9 100644 --- a/FirebaseMessaging/Tests/UnitTestsSwift/FIRMessagingAPITest.swift +++ b/FirebaseMessaging/Tests/UnitTestsSwift/FIRMessagingAPITest.swift @@ -94,7 +94,7 @@ func apis() { messaging.subscribe(toTopic: topic) messaging.unsubscribe(fromTopic: topic) messaging.unsubscribe(fromTopic: topic, completion: { error in - if let error = error { + if let error { switch error { // Handle errors in the new format. case MessagingError.timeout: diff --git a/FirebaseMessagingInterop.podspec b/FirebaseMessagingInterop.podspec index f8bbcca64f4..ce7c6ae1d21 100644 --- a/FirebaseMessagingInterop.podspec +++ b/FirebaseMessagingInterop.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseMessagingInterop' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Interfaces that allow other Firebase SDKs to use Messaging functionality.' s.description = <<-DESC diff --git a/FirebasePerformance.podspec b/FirebasePerformance.podspec index 7600d067e8e..8fa8c6314ba 100644 --- a/FirebasePerformance.podspec +++ b/FirebasePerformance.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebasePerformance' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Firebase Performance' s.description = <<-DESC diff --git a/FirebaseRemoteConfig.podspec b/FirebaseRemoteConfig.podspec index 2852224a16b..c3a54d7560a 100644 --- a/FirebaseRemoteConfig.podspec +++ b/FirebaseRemoteConfig.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseRemoteConfig' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Firebase Remote Config' s.description = <<-DESC diff --git a/FirebaseRemoteConfigInterop.podspec b/FirebaseRemoteConfigInterop.podspec index 9ddb0db4b28..b1f6059e549 100644 --- a/FirebaseRemoteConfigInterop.podspec +++ b/FirebaseRemoteConfigInterop.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseRemoteConfigInterop' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Interfaces that allow other Firebase SDKs to use Remote Config functionality.' s.description = <<-DESC diff --git a/FirebaseRemoteConfigSwift/Tests/FakeConsole/FakeConsoleTests.swift b/FirebaseRemoteConfigSwift/Tests/FakeConsole/FakeConsoleTests.swift index 73944fb9e9b..9f0bf1c188b 100644 --- a/FirebaseRemoteConfigSwift/Tests/FakeConsole/FakeConsoleTests.swift +++ b/FirebaseRemoteConfigSwift/Tests/FakeConsole/FakeConsoleTests.swift @@ -28,7 +28,7 @@ class FakeConsoleTests: APITestBase { func testChangedActivateWillNotFlag() { let expectation = self.expectation(description: #function) config.fetch { status, error in - if let error = error { + if let error { XCTFail("Fetch Error \(error)") } XCTAssertEqual(status, RemoteConfigFetchStatus.success) @@ -46,7 +46,7 @@ class FakeConsoleTests: APITestBase { let expectation2 = self.expectation(description: #function + "2") config.fetch { status, error in - if let error = error { + if let error { XCTFail("Fetch Error \(error)") } XCTAssertEqual(status, RemoteConfigFetchStatus.success) @@ -64,7 +64,7 @@ class FakeConsoleTests: APITestBase { let kFIRStorageIntegrationTestTimeout = 10.0 waitForExpectations(timeout: kFIRStorageIntegrationTestTimeout, handler: { error in - if let error = error { + if let error { print(error) } }) diff --git a/FirebaseRemoteConfigSwift/Tests/SwiftAPI/APITests.swift b/FirebaseRemoteConfigSwift/Tests/SwiftAPI/APITests.swift index d1b0b4a0489..7bf81c97a37 100644 --- a/FirebaseRemoteConfigSwift/Tests/SwiftAPI/APITests.swift +++ b/FirebaseRemoteConfigSwift/Tests/SwiftAPI/APITests.swift @@ -21,7 +21,7 @@ class APITests: APITestBase { func testFetchThenActivate() { let expectation = self.expectation(description: #function) config.fetch { status, error in - if let error = error { + if let error { XCTFail("Fetch Error \(error)") } XCTAssertEqual(status, RemoteConfigFetchStatus.success) @@ -37,7 +37,7 @@ class APITests: APITestBase { func testFetchWithExpirationThenActivate() { let expectation = self.expectation(description: #function) config.fetch(withExpirationDuration: 0) { status, error in - if let error = error { + if let error { XCTFail("Fetch Error \(error)") } XCTAssertEqual(status, RemoteConfigFetchStatus.success) @@ -54,7 +54,7 @@ class APITests: APITestBase { let expectation = self.expectation(description: #function) config.fetchAndActivate { status, error in XCTAssertEqual(status, .successFetchedFromRemote) - if let error = error { + if let error { XCTFail("Fetch and Activate Error \(error)") } XCTAssertEqual(self.config[Constants.key1].stringValue, Constants.value1) @@ -68,7 +68,7 @@ class APITests: APITestBase { func testUnchangedActivateWillFlag() { let expectation = self.expectation(description: #function) config.fetch { status, error in - if let error = error { + if let error { XCTFail("Fetch Error \(error)") } XCTAssertEqual(status, RemoteConfigFetchStatus.success) @@ -82,7 +82,7 @@ class APITests: APITestBase { waitForExpectations() let expectation2 = self.expectation(description: #function + "2") config.fetch { status, error in - if let error = error { + if let error { XCTFail("Fetch Error \(error)") } XCTAssertEqual(status, RemoteConfigFetchStatus.success) @@ -289,7 +289,7 @@ class APITests: APITestBase { let kTestTimeout = 10.0 waitForExpectations(timeout: kTestTimeout, handler: { error in - if let error = error { + if let error { print(error) } }) diff --git a/FirebaseRemoteConfigSwift/Tests/SwiftAPI/RemoteConfigConsole.swift b/FirebaseRemoteConfigSwift/Tests/SwiftAPI/RemoteConfigConsole.swift index b4be53d8340..0e4df6e6e05 100644 --- a/FirebaseRemoteConfigSwift/Tests/SwiftAPI/RemoteConfigConsole.swift +++ b/FirebaseRemoteConfigSwift/Tests/SwiftAPI/RemoteConfigConsole.swift @@ -46,7 +46,7 @@ class RemoteConfigConsole { perform(configRequest: .get) { latestConfigJSON in config = latestConfigJSON } - if let config = config { + if let config { saveConfig(config) } return config @@ -210,8 +210,8 @@ class RemoteConfigConsole { /// Perform a synchronous sync with remote config console. private func syncWithConsole() { - if let consoleConfig = activeRemoteConfig { - latestConfig = consoleConfig + if let activeRemoteConfig { + latestConfig = activeRemoteConfig } else { fatalError("Could not sync with console.") } diff --git a/FirebaseSessions.podspec b/FirebaseSessions.podspec index 9f71521aae6..623c449d14d 100644 --- a/FirebaseSessions.podspec +++ b/FirebaseSessions.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseSessions' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Firebase Sessions' s.description = <<-DESC diff --git a/FirebaseSessions/Sources/GoogleDataTransport+GoogleDataTransportProtocol.swift b/FirebaseSessions/Sources/GoogleDataTransport+GoogleDataTransportProtocol.swift index ebc15e9f423..9c04f9c9ba2 100644 --- a/FirebaseSessions/Sources/GoogleDataTransport+GoogleDataTransportProtocol.swift +++ b/FirebaseSessions/Sources/GoogleDataTransport+GoogleDataTransportProtocol.swift @@ -29,7 +29,7 @@ protocol GoogleDataTransportProtocol { extension GDTCORTransport: GoogleDataTransportProtocol { func logGDTEvent(event: GDTCOREvent, completion: @escaping (Result) -> Void) { sendDataEvent(event) { wasWritten, error in - if let error = error { + if let error { completion(.failure(error)) } else if !wasWritten { completion(.failure(GoogleDataTransportProtocolErrors.writeFailure)) diff --git a/FirebaseSessions/Sources/Installations+InstallationsProtocol.swift b/FirebaseSessions/Sources/Installations+InstallationsProtocol.swift index fcbf1231d6c..38ca1eafa9b 100644 --- a/FirebaseSessions/Sources/Installations+InstallationsProtocol.swift +++ b/FirebaseSessions/Sources/Installations+InstallationsProtocol.swift @@ -50,7 +50,7 @@ extension InstallationsProtocol { workingGroup.enter() installationID { (installationID: String?, error: Error?) in - if let installationID = installationID { + if let installationID { intallationComplete = installationID } else if let error = error { errorComplete = error @@ -67,10 +67,10 @@ extension InstallationsProtocol { completion(.failure(FirebaseSessionsError.SessionInstallationsTimeOutError)) return default: - if let installationID = intallationComplete { - completion(.success((installationID, authTokenComplete))) - } else if let error = errorComplete { - completion(.failure(error)) + if let intallationComplete { + completion(.success((intallationComplete, authTokenComplete))) + } else if let errorComplete { + completion(.failure(errorComplete)) } } } diff --git a/FirebaseSessions/Sources/Settings/SettingsDownloadClient.swift b/FirebaseSessions/Sources/Settings/SettingsDownloadClient.swift index aaea90941dc..1d2a95a3cc5 100644 --- a/FirebaseSessions/Sources/Settings/SettingsDownloadClient.swift +++ b/FirebaseSessions/Sources/Settings/SettingsDownloadClient.swift @@ -56,7 +56,7 @@ class SettingsDownloader: SettingsDownloadClient { case let .success(installationsInfo): let request = self.buildRequest(url: validURL, fiid: installationsInfo.0) let task = URLSession.shared.dataTask(with: request) { data, response, error in - if let data = data { + if let data { if let dict = try? JSONSerialization.jsonObject(with: data) as? [String: Any] { completion(.success(dict)) } else { @@ -64,7 +64,7 @@ class SettingsDownloader: SettingsDownloadClient { .JSONParseError("Failed to parse JSON to dictionary") )) } - } else if let error = error { + } else if let error { completion(.failure(.URLSessionError(error.localizedDescription))) } } diff --git a/FirebaseSharedSwift.podspec b/FirebaseSharedSwift.podspec index 37443892fce..1e0c02b9e86 100644 --- a/FirebaseSharedSwift.podspec +++ b/FirebaseSharedSwift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseSharedSwift' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Shared Swift Extensions for Firebase' s.description = <<-DESC diff --git a/FirebaseStorage.podspec b/FirebaseStorage.podspec index af5df133bb7..2bd9d3eab79 100644 --- a/FirebaseStorage.podspec +++ b/FirebaseStorage.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FirebaseStorage' - s.version = '10.25.0' + s.version = '10.27.0' s.summary = 'Firebase Storage' s.description = <<-DESC diff --git a/FirebaseStorage/Sources/Internal/StorageDeleteTask.swift b/FirebaseStorage/Sources/Internal/StorageDeleteTask.swift index 086e8facf14..04891ef5909 100644 --- a/FirebaseStorage/Sources/Internal/StorageDeleteTask.swift +++ b/FirebaseStorage/Sources/Internal/StorageDeleteTask.swift @@ -63,7 +63,7 @@ class StorageDeleteTask: StorageTask, StorageTaskManagement { self.fetcherCompletion = { [weak self] (data: Data?, error: NSError?) in guard let self = self else { return } - if let error = error, self.error == nil { + if let error, self.error == nil { self.error = StorageErrorCode.error(withServerError: error, ref: self.reference) } self.taskCompletion?(self.error) diff --git a/FirebaseStorage/Sources/Internal/StorageGetDownloadURLTask.swift b/FirebaseStorage/Sources/Internal/StorageGetDownloadURLTask.swift index 72b50a11220..2cca8acdca2 100644 --- a/FirebaseStorage/Sources/Internal/StorageGetDownloadURLTask.swift +++ b/FirebaseStorage/Sources/Internal/StorageGetDownloadURLTask.swift @@ -64,12 +64,12 @@ class StorageGetDownloadURLTask: StorageTask, StorageTaskManagement { self.fetcherCompletion = { [weak self] (data: Data?, error: NSError?) in guard let self = self else { return } var downloadURL: URL? - if let error = error { + if let error { if self.error == nil { self.error = StorageErrorCode.error(withServerError: error, ref: self.reference) } } else { - if let data = data, + if let data, let responseDictionary = try? JSONSerialization .jsonObject(with: data) as? [String: Any] { downloadURL = self.downloadURLFromMetadataDictionary(responseDictionary) diff --git a/FirebaseStorage/Sources/Internal/StorageGetMetadataTask.swift b/FirebaseStorage/Sources/Internal/StorageGetMetadataTask.swift index 40f65a7b5d8..5202394631a 100644 --- a/FirebaseStorage/Sources/Internal/StorageGetMetadataTask.swift +++ b/FirebaseStorage/Sources/Internal/StorageGetMetadataTask.swift @@ -65,12 +65,12 @@ class StorageGetMetadataTask: StorageTask, StorageTaskManagement { self.fetcherCompletion = { [weak self] (data: Data?, error: NSError?) in guard let self = self else { return } var metadata: StorageMetadata? - if let error = error { + if let error { if self.error == nil { self.error = StorageErrorCode.error(withServerError: error, ref: self.reference) } } else { - if let data = data, + if let data, let responseDictionary = try? JSONSerialization .jsonObject(with: data) as? [String: AnyHashable] { metadata = StorageMetadata(dictionary: responseDictionary) diff --git a/FirebaseStorage/Sources/Internal/StorageListTask.swift b/FirebaseStorage/Sources/Internal/StorageListTask.swift index 94c872aae28..10b22d95b96 100644 --- a/FirebaseStorage/Sources/Internal/StorageListTask.swift +++ b/FirebaseStorage/Sources/Internal/StorageListTask.swift @@ -92,11 +92,11 @@ class StorageListTask: StorageTask, StorageTaskManagement { // items // to return per page. This removes the need to backfill results if Firebase Storage filters // objects that are considered invalid (such as items with two consecutive slashes). - if let pageSize = self.pageSize { + if let pageSize { queryParams["maxResults"] = "\(pageSize)" } - if let previousPageToken = self.previousPageToken { + if let previousPageToken { queryParams["pageToken"] = previousPageToken } @@ -116,10 +116,10 @@ class StorageListTask: StorageTask, StorageTaskManagement { self.fetcherCompletion = { [weak self] (data: Data?, error: NSError?) in guard let self = self else { return } var listResult: StorageListResult? - if let error = error, self.error == nil { + if let error, self.error == nil { self.error = StorageErrorCode.error(withServerError: error, ref: self.reference) } else { - if let data = data, + if let data, let responseDictionary = try? JSONSerialization .jsonObject(with: data) as? [String: Any] { listResult = StorageListResult(with: responseDictionary, reference: self.reference) diff --git a/FirebaseStorage/Sources/Internal/StoragePath.swift b/FirebaseStorage/Sources/Internal/StoragePath.swift index d094771eca3..d27149af40e 100644 --- a/FirebaseStorage/Sources/Internal/StoragePath.swift +++ b/FirebaseStorage/Sources/Internal/StoragePath.swift @@ -135,7 +135,7 @@ class StoragePath: NSCopying, Equatable { init(with bucket: String, object: String? = nil) { self.bucket = bucket - if let object = object { + if let object { self.object = StoragePath.standardizedPathForString(object) } else { self.object = nil diff --git a/FirebaseStorage/Sources/Internal/StorageTokenAuthorizer.swift b/FirebaseStorage/Sources/Internal/StorageTokenAuthorizer.swift index f44ae26e793..217f8775116 100644 --- a/FirebaseStorage/Sources/Internal/StorageTokenAuthorizer.swift +++ b/FirebaseStorage/Sources/Internal/StorageTokenAuthorizer.swift @@ -38,7 +38,7 @@ class StorageTokenAuthorizer: NSObject, GTMSessionFetcherAuthorizer { var tokenError: NSError? let callbackQueue = fetcherService.callbackQueue ?? DispatchQueue.main let fetchTokenGroup = DispatchGroup() - if let auth = auth { + if let auth { fetchTokenGroup.enter() auth.getToken(forcingRefresh: false) { token, error in if let error = error as? NSError { @@ -51,14 +51,14 @@ class StorageTokenAuthorizer: NSObject, GTMSessionFetcherAuthorizer { tokenError = NSError(domain: "FIRStorageErrorDomain", code: StorageErrorCode.unauthenticated.rawValue, userInfo: errorDictionary) - } else if let token = token { + } else if let token { let firebaseToken = "Firebase \(token)" request?.setValue(firebaseToken, forHTTPHeaderField: "Authorization") } fetchTokenGroup.leave() } } - if let appCheck = appCheck { + if let appCheck { fetchTokenGroup.enter() appCheck.getToken(forcingRefresh: false) { tokenResult in request?.setValue(tokenResult.token, forHTTPHeaderField: "X-Firebase-AppCheck") diff --git a/FirebaseStorage/Sources/Internal/StorageUpdateMetadataTask.swift b/FirebaseStorage/Sources/Internal/StorageUpdateMetadataTask.swift index bc75c48e65c..dad1dcb4886 100644 --- a/FirebaseStorage/Sources/Internal/StorageUpdateMetadataTask.swift +++ b/FirebaseStorage/Sources/Internal/StorageUpdateMetadataTask.swift @@ -73,12 +73,12 @@ class StorageUpdateMetadataTask: StorageTask, StorageTaskManagement { self.fetcherCompletion = { [weak self] (data: Data?, error: NSError?) in guard let self = self else { return } var metadata: StorageMetadata? - if let error = error { + if let error { if self.error == nil { self.error = StorageErrorCode.error(withServerError: error, ref: self.reference) } } else { - if let data = data, + if let data, let responseDictionary = try? JSONSerialization .jsonObject(with: data) as? [String: AnyHashable] { metadata = StorageMetadata(dictionary: responseDictionary) diff --git a/FirebaseStorage/Sources/Internal/StorageUtils.swift b/FirebaseStorage/Sources/Internal/StorageUtils.swift index 457a70aa4ec..1c0ea561eb0 100644 --- a/FirebaseStorage/Sources/Internal/StorageUtils.swift +++ b/FirebaseStorage/Sources/Internal/StorageUtils.swift @@ -38,7 +38,7 @@ class StorageUtils { components.host = reference.storage.host components.port = reference.storage.port - if let queryParams = queryParams { + if let queryParams { var queryItems = [URLQueryItem]() for (key, value) in queryParams { queryItems.append(URLQueryItem(name: key, value: value)) diff --git a/FirebaseStorage/Sources/Result.swift b/FirebaseStorage/Sources/Result.swift index d1260fe57f9..931794cbfb1 100644 --- a/FirebaseStorage/Sources/Result.swift +++ b/FirebaseStorage/Sources/Result.swift @@ -26,9 +26,9 @@ private func getResultCallback(completion: @escaping (Result) -> Vo _: Error?) -> Void { return { (value: T?, error: Error?) in - if let value = value { + if let value { completion(.success(value)) - } else if let error = error { + } else if let error { completion(.failure(StorageError.swiftConvert(objcError: error as NSError))) } else { completion(.failure(StorageError.internalError("Internal failure in getResultCallback"))) diff --git a/FirebaseStorage/Sources/StorageDownloadTask.swift b/FirebaseStorage/Sources/StorageDownloadTask.swift index 62217182c0e..8f9f0332393 100644 --- a/FirebaseStorage/Sources/StorageDownloadTask.swift +++ b/FirebaseStorage/Sources/StorageDownloadTask.swift @@ -116,7 +116,7 @@ open class StorageDownloadTask: StorageObservableTask, StorageTaskManagement { request.url = components?.url var fetcher: GTMSessionFetcher - if let resumeData = resumeData { + if let resumeData { fetcher = GTMSessionFetcher(downloadResumeData: resumeData) fetcher.comment = "Resuming DownloadTask" } else { @@ -125,7 +125,7 @@ open class StorageDownloadTask: StorageObservableTask, StorageTaskManagement { } fetcher.maxRetryInterval = self.reference.storage.maxDownloadRetryInterval - if let fileURL = self.fileURL { + if let fileURL { // Handle file downloads fetcher.destinationFileURL = fileURL fetcher.downloadProgressBlock = { [weak self] (bytesWritten: Int64, @@ -163,7 +163,7 @@ open class StorageDownloadTask: StorageObservableTask, StorageTaskManagement { self.fire(for: .progress, snapshot: self.snapshot) // Handle potential issues with download - if let error = error { + if let error { self.state = .failed self.error = StorageErrorCode.error(withServerError: error, ref: self.reference) self.fire(for: .failure, snapshot: self.snapshot) @@ -171,7 +171,7 @@ open class StorageDownloadTask: StorageObservableTask, StorageTaskManagement { } // Download completed successfully, fire completion callbacks self.state = .success - if let data = data { + if let data { self.downloadData = data } self.fire(for: .success, snapshot: self.snapshot) diff --git a/FirebaseStorage/Sources/StorageError.swift b/FirebaseStorage/Sources/StorageError.swift index 866e07a32cf..68543f50aba 100644 --- a/FirebaseStorage/Sources/StorageError.swift +++ b/FirebaseStorage/Sources/StorageError.swift @@ -76,7 +76,7 @@ public let StorageErrorDomain: String = "FIRStorageErrorDomain" */ static func error(withInvalidRequest request: Data?) -> NSError { var requestString: String - if let request = request { + if let request { requestString = String(data: request, encoding: .utf8) ?? "" } else { requestString = "" diff --git a/FirebaseStorage/Sources/StorageReference.swift b/FirebaseStorage/Sources/StorageReference.swift index d3d45d6e2df..92a547b3f14 100644 --- a/FirebaseStorage/Sources/StorageReference.swift +++ b/FirebaseStorage/Sources/StorageReference.swift @@ -286,7 +286,7 @@ import Foundation queue: storage.dispatchQueue, file: fileURL) - if let completion = completion { + if let completion { task.completionURL = completion let callbackQueue = fetcherService.callbackQueue ?? DispatchQueue.main @@ -330,7 +330,7 @@ import Foundation var paginatedCompletion: ((_: StorageListResult?, _: Error?) -> Void)? paginatedCompletion = { (_ listResult: StorageListResult?, _ error: Error?) in - if let error = error { + if let error { completion(nil, error) return } @@ -531,7 +531,7 @@ import Foundation open func delete() async throws { return try await withCheckedThrowingContinuation { continuation in self.delete { error in - if let error = error { + if let error { continuation.resume(throwing: error) } else { continuation.resume() @@ -595,7 +595,7 @@ import Foundation private func startAndObserveUploadTask(task: StorageUploadTask, completion: ((_: StorageMetadata?, _: Error?) -> Void)?) { - if let completion = completion { + if let completion { task.completionMetadata = completion let callbackQueue = storage.fetcherServiceForApp.callbackQueue ?? DispatchQueue.main diff --git a/FirebaseStorage/Sources/StorageUploadTask.swift b/FirebaseStorage/Sources/StorageUploadTask.swift index 0d1e904661f..8c99e8c4a28 100644 --- a/FirebaseStorage/Sources/StorageUploadTask.swift +++ b/FirebaseStorage/Sources/StorageUploadTask.swift @@ -87,10 +87,10 @@ import Foundation chunkSize: self.reference.storage.uploadChunkSizeBytes, fetcherService: self.fetcherService ) - if let data = self.uploadData { - uploadFetcher.uploadData = data + if let uploadData { + uploadFetcher.uploadData = uploadData uploadFetcher.comment = "Data UploadTask" - } else if let fileURL = self.fileURL { + } else if let fileURL { uploadFetcher.uploadFileURL = fileURL uploadFetcher.comment = "File UploadTask" @@ -120,7 +120,7 @@ import Foundation self.fire(for: .progress, snapshot: self.snapshot) // Handle potential issues with upload - if let error = error { + if let error { self.state = .failed self.error = StorageErrorCode.error(withServerError: error, ref: self.reference) self.metadata = self.uploadMetadata diff --git a/FirebaseStorage/Tests/Integration/StorageAsyncAwait.swift b/FirebaseStorage/Tests/Integration/StorageAsyncAwait.swift index fafdb21906c..f8729a5b675 100644 --- a/FirebaseStorage/Tests/Integration/StorageAsyncAwait.swift +++ b/FirebaseStorage/Tests/Integration/StorageAsyncAwait.swift @@ -413,7 +413,7 @@ class StorageAsyncAwait: StorageIntegrationCommon { let kTestTimeout = 60.0 waitForExpectations(timeout: kTestTimeout, handler: { error in - if let error = error { + if let error { print(error) } }) diff --git a/FirebaseStorage/Tests/Integration/StorageIntegration.swift b/FirebaseStorage/Tests/Integration/StorageIntegration.swift index 980ab243108..2f407dc7427 100644 --- a/FirebaseStorage/Tests/Integration/StorageIntegration.swift +++ b/FirebaseStorage/Tests/Integration/StorageIntegration.swift @@ -847,7 +847,7 @@ class StorageResultTests: StorageIntegrationCommon { let kFIRStorageIntegrationTestTimeout = 100.0 waitForExpectations(timeout: kFIRStorageIntegrationTestTimeout, handler: { error in - if let error = error { + if let error { print(error) } }) diff --git a/FirebaseStorage/Tests/Integration/StorageIntegrationCommon.swift b/FirebaseStorage/Tests/Integration/StorageIntegrationCommon.swift index 47c4fb6f37c..2cc09981167 100644 --- a/FirebaseStorage/Tests/Integration/StorageIntegrationCommon.swift +++ b/FirebaseStorage/Tests/Integration/StorageIntegrationCommon.swift @@ -101,7 +101,7 @@ class StorageIntegrationCommon: XCTestCase { let kTestTimeout = 60.0 waitForExpectations(timeout: kTestTimeout, handler: { error in - if let error = error { + if let error { print(error) } }) diff --git a/FirebaseStorage/Tests/Unit/StorageTestHelpers.swift b/FirebaseStorage/Tests/Unit/StorageTestHelpers.swift index 737be5e6acf..9d6b906d0f1 100644 --- a/FirebaseStorage/Tests/Unit/StorageTestHelpers.swift +++ b/FirebaseStorage/Tests/Unit/StorageTestHelpers.swift @@ -45,7 +45,7 @@ class StorageTestHelpers: XCTestCase { func waitForExpectation(test: XCTest) { waitForExpectations(timeout: 10) { error in - if let error = error { + if let error { print("Error \(error)") } } @@ -54,7 +54,7 @@ class StorageTestHelpers: XCTestCase { func successBlock(withMetadata metadata: StorageMetadata? = nil) -> GTMSessionFetcherTestBlock { var data: Data? - if let metadata = metadata { + if let metadata { data = try? JSONSerialization.data(withJSONObject: metadata.dictionaryRepresentation()) } return block(forData: data, url: nil, statusCode: 200) @@ -99,7 +99,7 @@ class StorageTestHelpers: XCTestCase { statusCode code: Int) -> GTMSessionFetcherTestBlock { let block = { (fetcher: GTMSessionFetcher, response: GTMSessionFetcherTestResponse) in let fetcherURL = fetcher.request?.url! - if let url = url { + if let url { XCTAssertEqual(url, fetcherURL) } let httpResponse = HTTPURLResponse( @@ -111,7 +111,7 @@ class StorageTestHelpers: XCTestCase { var error: NSError? if code >= 400 { var userInfo: [String: Any]? - if let data = data { + if let data { userInfo = ["data": data] } error = NSError(domain: "com.google.HTTPStatus", code: code, userInfo: userInfo) diff --git a/FirebaseVertexAI-Docs.not_podspec b/FirebaseVertexAI-Docs.not_podspec new file mode 100644 index 00000000000..7967cc616c4 --- /dev/null +++ b/FirebaseVertexAI-Docs.not_podspec @@ -0,0 +1,47 @@ +Pod::Spec.new do |s| + s.name = 'FirebaseVertexAI-Docs' + s.version = '10.27.0' + s.summary = 'Firebase Vertex AI' + + s.description = <<-DESC + Placeholder podspec for docsgen only. Do not use this pod. + + NOTE: Rename the file extension from `.not_podspec` to `.podspec` before + running `pod gen` for docs generation. + 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 = '11.0' + + s.ios.deployment_target = ios_deployment_target + s.osx.deployment_target = osx_deployment_target + + s.cocoapods_version = '>= 1.12.0' + s.prefix_header_file = false + + s.source_files = [ + 'FirebaseVertexAI/Sources/**/*.swift', + ] + + s.swift_version = '5.3' + + s.framework = 'Foundation' + s.ios.framework = 'UIKit' + s.osx.framework = 'AppKit' + + s.dependency 'FirebaseAppCheckInterop', '~> 10.17' + s.dependency 'FirebaseAuthInterop', '~> 10.25' + s.dependency 'FirebaseCore', '~> 10.5' + s.dependency 'FirebaseCoreExtension', '~> 10.0' +end diff --git a/FirebaseVertexAI/CHANGELOG.md b/FirebaseVertexAI/CHANGELOG.md new file mode 100644 index 00000000000..7017d26ce58 --- /dev/null +++ b/FirebaseVertexAI/CHANGELOG.md @@ -0,0 +1,14 @@ +# 10.27.0 +- [changed] Removed uses of the `gemini-1.5-pro-preview-0409` model in docs and + samples. Developers should now use `gemini-1.5-pro-preview-0514` or + `gemini-1.5-flash-preview-0514`; see + [available model names](https://firebase.google.com/docs/vertex-ai/gemini-models#available-model-names) + for more details. (#12979) +- [changed] Logged additional details when required APIs for Vertex AI are + not enabled or response payloads when requests fail. (#13007, #13009) + +# 10.26.0 +- [feature] Initial release of the Vertex AI for Firebase SDK (public preview). + Learn how to + [get started](https://firebase.google.com/docs/vertex-ai/get-started?platform=ios) + with the SDK in your app. diff --git a/FirebaseVertexAI/README.md b/FirebaseVertexAI/README.md new file mode 100644 index 00000000000..398a183eecb --- /dev/null +++ b/FirebaseVertexAI/README.md @@ -0,0 +1,8 @@ +# Vertex AI for Firebase SDK + +**Preview**: Vertex AI for Firebase is in Public Preview, which means that the product is +not subject to any SLA or deprecation policy and could change in backwards-incompatible +ways. + +- For developer documentation, please visit https://firebase.google.com/docs/vertex-ai. +- Try out the [sample app](Sample/README.md) to get started. diff --git a/FirebaseVertexAI/Sample/ChatSample/Screens/ConversationScreen.swift b/FirebaseVertexAI/Sample/ChatSample/Screens/ConversationScreen.swift index a3044a1f430..78c903e3412 100644 --- a/FirebaseVertexAI/Sample/ChatSample/Screens/ConversationScreen.swift +++ b/FirebaseVertexAI/Sample/ChatSample/Screens/ConversationScreen.swift @@ -94,6 +94,8 @@ struct ConversationScreen: View { } private func sendOrStop() { + focusedField = nil + if viewModel.busy { viewModel.stop() } else { diff --git a/FirebaseVertexAI/Sample/ChatSample/ViewModels/ConversationViewModel.swift b/FirebaseVertexAI/Sample/ChatSample/ViewModels/ConversationViewModel.swift index 465789be387..d8020b3ac41 100644 --- a/FirebaseVertexAI/Sample/ChatSample/ViewModels/ConversationViewModel.swift +++ b/FirebaseVertexAI/Sample/ChatSample/ViewModels/ConversationViewModel.swift @@ -36,7 +36,7 @@ class ConversationViewModel: ObservableObject { private var chatTask: Task? init() { - model = VertexAI.generativeModel(modelName: "gemini-1.0-pro", location: "us-central1") + model = VertexAI.vertexAI().generativeModel(modelName: "gemini-1.5-flash-preview-0514") chat = model.startChat() } diff --git a/FirebaseVertexAI/Sample/ChatSample/Views/ErrorDetailsView.swift b/FirebaseVertexAI/Sample/ChatSample/Views/ErrorDetailsView.swift index 399777ad1e8..dc5ce8f9561 100644 --- a/FirebaseVertexAI/Sample/ChatSample/Views/ErrorDetailsView.swift +++ b/FirebaseVertexAI/Sample/ChatSample/Views/ErrorDetailsView.swift @@ -142,22 +142,6 @@ struct ErrorDetailsView: View { SafetyRatingsSection(ratings: ratings) } - case GenerateContentError.invalidAPIKey: - Section("Error Type") { - Text("Invalid API Key") - } - - Section("Details") { - SubtitleFormRow(title: "Error description", value: error.localizedDescription) - SubtitleMarkdownFormRow( - title: "Help", - value: """ - The `API_KEY` provided in the `GoogleService-Info.plist` file is invalid. Download a - new copy of the file from the [Firebase Console](https://console.firebase.google.com). - """ - ) - } - default: Section("Error Type") { Text("Some other error") @@ -192,8 +176,7 @@ struct ErrorDetailsView: View { ], finishReason: FinishReason.maxTokens, citationMetadata: nil), - ], - promptFeedback: nil) + ]) ) return ErrorDetailsView(error: error) @@ -216,17 +199,8 @@ struct ErrorDetailsView: View { ], finishReason: FinishReason.other, citationMetadata: nil), - ], - promptFeedback: nil) + ]) ) return ErrorDetailsView(error: error) } - -#Preview("Invalid API Key") { - ErrorDetailsView(error: GenerateContentError.invalidAPIKey) -} - -#Preview("Unsupported User Location") { - ErrorDetailsView(error: GenerateContentError.unsupportedUserLocation) -} diff --git a/FirebaseVertexAI/Sample/ChatSample/Views/ErrorView.swift b/FirebaseVertexAI/Sample/ChatSample/Views/ErrorView.swift index 1307eee62d4..d4db2d67dc5 100644 --- a/FirebaseVertexAI/Sample/ChatSample/Views/ErrorView.swift +++ b/FirebaseVertexAI/Sample/ChatSample/Views/ErrorView.swift @@ -51,8 +51,7 @@ struct ErrorView: View { ], finishReason: FinishReason.other, citationMetadata: nil), - ], - promptFeedback: nil) + ]) ) List { MessageView(message: ChatMessage.samples[0]) diff --git a/FirebaseVertexAI/Sample/FunctionCallingSample/Screens/FunctionCallingScreen.swift b/FirebaseVertexAI/Sample/FunctionCallingSample/Screens/FunctionCallingScreen.swift new file mode 100644 index 00000000000..f16da39e22f --- /dev/null +++ b/FirebaseVertexAI/Sample/FunctionCallingSample/Screens/FunctionCallingScreen.swift @@ -0,0 +1,131 @@ +// 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 FirebaseVertexAI +import GenerativeAIUIComponents +import SwiftUI + +struct FunctionCallingScreen: View { + @EnvironmentObject + var viewModel: FunctionCallingViewModel + + @State + private var userPrompt = "What is 100 Euros in U.S. Dollars?" + + enum FocusedField: Hashable { + case message + } + + @FocusState + var focusedField: FocusedField? + + var body: some View { + VStack { + ScrollViewReader { scrollViewProxy in + List { + Text("Interact with a currency conversion API using function calling in Gemini.") + ForEach(viewModel.messages) { message in + MessageView(message: message) + } + if let error = viewModel.error { + ErrorView(error: error) + .tag("errorView") + } + } + .listStyle(.plain) + .onChange(of: viewModel.messages, perform: { newValue in + if viewModel.hasError { + // Wait for a short moment to make sure we can actually scroll to the bottom. + DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { + withAnimation { + scrollViewProxy.scrollTo("errorView", anchor: .bottom) + } + focusedField = .message + } + } else { + guard let lastMessage = viewModel.messages.last else { return } + + // Wait for a short moment to make sure we can actually scroll to the bottom. + DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { + withAnimation { + scrollViewProxy.scrollTo(lastMessage.id, anchor: .bottom) + } + focusedField = .message + } + } + }) + .onTapGesture { + focusedField = nil + } + } + InputField("Message...", text: $userPrompt) { + Image(systemName: viewModel.busy ? "stop.circle.fill" : "arrow.up.circle.fill") + .font(.title) + } + .focused($focusedField, equals: .message) + .onSubmit { sendOrStop() } + } + .toolbar { + ToolbarItem(placement: .primaryAction) { + Button(action: newChat) { + Image(systemName: "square.and.pencil") + } + } + } + .navigationTitle("Function Calling") + .onAppear { + focusedField = .message + } + } + + private func sendMessage() { + Task { + let prompt = userPrompt + userPrompt = "" + await viewModel.sendMessage(prompt, streaming: true) + } + } + + private func sendOrStop() { + if viewModel.busy { + viewModel.stop() + } else { + sendMessage() + } + } + + private func newChat() { + viewModel.startNewChat() + } +} + +struct FunctionCallingScreen_Previews: PreviewProvider { + struct ContainerView: View { + @EnvironmentObject + var viewModel: FunctionCallingViewModel + + var body: some View { + FunctionCallingScreen() + .onAppear { + viewModel.messages = ChatMessage.samples + } + } + } + + static var previews: some View { + NavigationStack { + FunctionCallingScreen().environmentObject(FunctionCallingViewModel()) + } + } +} diff --git a/FirebaseVertexAI/Sample/FunctionCallingSample/ViewModels/FunctionCallingViewModel.swift b/FirebaseVertexAI/Sample/FunctionCallingSample/ViewModels/FunctionCallingViewModel.swift new file mode 100644 index 00000000000..3b6074b8cd5 --- /dev/null +++ b/FirebaseVertexAI/Sample/FunctionCallingSample/ViewModels/FunctionCallingViewModel.swift @@ -0,0 +1,264 @@ +// 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 FirebaseVertexAI +import Foundation +import UIKit + +@MainActor +class FunctionCallingViewModel: ObservableObject { + /// This array holds both the user's and the system's chat messages + @Published var messages = [ChatMessage]() + + /// Indicates we're waiting for the model to finish + @Published var busy = false + + @Published var error: Error? + var hasError: Bool { + return error != nil + } + + /// Function calls pending processing + private var functionCalls = [FunctionCall]() + + private var model: GenerativeModel + private var chat: Chat + + private var chatTask: Task? + + init() { + model = VertexAI.vertexAI().generativeModel( + modelName: "gemini-1.5-flash-preview-0514", + tools: [Tool(functionDeclarations: [ + FunctionDeclaration( + name: "get_exchange_rate", + description: "Get the exchange rate for currencies between countries", + parameters: [ + "currency_from": Schema( + type: .string, + format: "enum", + description: "The currency to convert from in ISO 4217 format", + enumValues: ["USD", "EUR", "JPY", "GBP", "AUD", "CAD"] + ), + "currency_to": Schema( + type: .string, + format: "enum", + description: "The currency to convert to in ISO 4217 format", + enumValues: ["USD", "EUR", "JPY", "GBP", "AUD", "CAD"] + ), + ], + requiredParameters: ["currency_from", "currency_to"] + ), + ])] + ) + chat = model.startChat() + } + + func sendMessage(_ text: String, streaming: Bool = true) async { + error = nil + chatTask?.cancel() + + chatTask = Task { + busy = true + defer { + busy = false + } + + // first, add the user's message to the chat + let userMessage = ChatMessage(message: text, participant: .user) + messages.append(userMessage) + + // add a pending message while we're waiting for a response from the backend + let systemMessage = ChatMessage.pending(participant: .system) + messages.append(systemMessage) + + print(messages) + do { + repeat { + if streaming { + try await internalSendMessageStreaming(text) + } else { + try await internalSendMessage(text) + } + } while !functionCalls.isEmpty + } catch { + self.error = error + print(error.localizedDescription) + messages.removeLast() + } + } + } + + func startNewChat() { + stop() + error = nil + chat = model.startChat() + messages.removeAll() + } + + func stop() { + chatTask?.cancel() + error = nil + } + + private func internalSendMessageStreaming(_ text: String) async throws { + let functionResponses = try await processFunctionCalls() + let responseStream: AsyncThrowingStream + if functionResponses.isEmpty { + responseStream = chat.sendMessageStream(text) + } else { + for functionResponse in functionResponses { + messages.insert(functionResponse.chatMessage(), at: messages.count - 1) + } + responseStream = chat.sendMessageStream(functionResponses.modelContent()) + } + for try await chunk in responseStream { + processResponseContent(content: chunk) + } + } + + private func internalSendMessage(_ text: String) async throws { + let functionResponses = try await processFunctionCalls() + let response: GenerateContentResponse + if functionResponses.isEmpty { + response = try await chat.sendMessage(text) + } else { + for functionResponse in functionResponses { + messages.insert(functionResponse.chatMessage(), at: messages.count - 1) + } + response = try await chat.sendMessage(functionResponses.modelContent()) + } + processResponseContent(content: response) + } + + func processResponseContent(content: GenerateContentResponse) { + guard let candidate = content.candidates.first else { + fatalError("No candidate.") + } + + for part in candidate.content.parts { + switch part { + case let .text(text): + // replace pending message with backend response + messages[messages.count - 1].message += text + messages[messages.count - 1].pending = false + case let .functionCall(functionCall): + messages.insert(functionCall.chatMessage(), at: messages.count - 1) + functionCalls.append(functionCall) + case .data, .fileData, .functionResponse: + fatalError("Unsupported response content.") + } + } + } + + func processFunctionCalls() async throws -> [FunctionResponse] { + var functionResponses = [FunctionResponse]() + for functionCall in functionCalls { + switch functionCall.name { + case "get_exchange_rate": + let exchangeRates = getExchangeRate(args: functionCall.args) + functionResponses.append(FunctionResponse( + name: "get_exchange_rate", + response: exchangeRates + )) + default: + fatalError("Unknown function named \"\(functionCall.name)\".") + } + } + functionCalls = [] + + return functionResponses + } + + // MARK: - Callable Functions + + func getExchangeRate(args: JSONObject) -> JSONObject { + // 1. Validate and extract the parameters provided by the model (from a `FunctionCall`) + guard case let .string(from) = args["currency_from"] else { + fatalError("Missing `currency_from` parameter.") + } + guard case let .string(to) = args["currency_to"] else { + fatalError("Missing `currency_to` parameter.") + } + + // 2. Get the exchange rate + let allRates: [String: [String: Double]] = [ + "AUD": ["CAD": 0.89265, "EUR": 0.6072, "GBP": 0.51714, "JPY": 97.75, "USD": 0.66379], + "CAD": ["AUD": 1.1203, "EUR": 0.68023, "GBP": 0.57933, "JPY": 109.51, "USD": 0.74362], + "EUR": ["AUD": 1.6469, "CAD": 1.4701, "GBP": 0.85168, "JPY": 160.99, "USD": 1.0932], + "GBP": ["AUD": 1.9337, "CAD": 1.7261, "EUR": 1.1741, "JPY": 189.03, "USD": 1.2836], + "JPY": ["AUD": 0.01023, "CAD": 0.00913, "EUR": 0.00621, "GBP": 0.00529, "USD": 0.00679], + "USD": ["AUD": 1.5065, "CAD": 1.3448, "EUR": 0.91475, "GBP": 0.77907, "JPY": 147.26], + ] + guard let fromRates = allRates[from] else { + return ["error": .string("No data for currency \(from).")] + } + guard let toRate = fromRates[to] else { + return ["error": .string("No data for currency \(to).")] + } + + // 3. Return the exchange rates as a JSON object (returned to the model in a `FunctionResponse`) + return ["rates": .number(toRate)] + } +} + +private extension FunctionCall { + func chatMessage() -> ChatMessage { + let encoder = JSONEncoder() + encoder.outputFormatting = .prettyPrinted + + let jsonData: Data + do { + jsonData = try encoder.encode(self) + } catch { + fatalError("JSON Encoding Failed: \(error.localizedDescription)") + } + guard let json = String(data: jsonData, encoding: .utf8) else { + fatalError("Failed to convert JSON data to a String.") + } + let messageText = "Function call requested by model:\n```\n\(json)\n```" + + return ChatMessage(message: messageText, participant: .system) + } +} + +private extension FunctionResponse { + func chatMessage() -> ChatMessage { + let encoder = JSONEncoder() + encoder.outputFormatting = .prettyPrinted + + let jsonData: Data + do { + jsonData = try encoder.encode(self) + } catch { + fatalError("JSON Encoding Failed: \(error.localizedDescription)") + } + guard let json = String(data: jsonData, encoding: .utf8) else { + fatalError("Failed to convert JSON data to a String.") + } + let messageText = "Function response returned by app:\n```\n\(json)\n```" + + return ChatMessage(message: messageText, participant: .user) + } +} + +private extension [FunctionResponse] { + func modelContent() -> [ModelContent] { + return self.map { ModelContent( + role: "function", + parts: [ModelContent.Part.functionResponse($0)] + ) + } + } +} diff --git a/FirebaseVertexAI/Sample/GenerativeAIMultimodalSample/GenerativeAIMultimodalSampleApp.swift b/FirebaseVertexAI/Sample/GenerativeAIMultimodalSample/GenerativeAIMultimodalSampleApp.swift deleted file mode 100644 index 49565de52d1..00000000000 --- a/FirebaseVertexAI/Sample/GenerativeAIMultimodalSample/GenerativeAIMultimodalSampleApp.swift +++ /dev/null @@ -1,31 +0,0 @@ -// 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 FirebaseCore -import SwiftUI - -@main -struct GenerativeAIMultimodalSampleApp: App { - init() { - FirebaseApp.configure() - } - - var body: some Scene { - WindowGroup { - NavigationStack { - PhotoReasoningScreen() - } - } - } -} diff --git a/FirebaseVertexAI/Sample/GenerativeAIMultimodalSample/Screens/PhotoReasoningScreen.swift b/FirebaseVertexAI/Sample/GenerativeAIMultimodalSample/Screens/PhotoReasoningScreen.swift index 98f327585db..930214770d8 100644 --- a/FirebaseVertexAI/Sample/GenerativeAIMultimodalSample/Screens/PhotoReasoningScreen.swift +++ b/FirebaseVertexAI/Sample/GenerativeAIMultimodalSample/Screens/PhotoReasoningScreen.swift @@ -20,9 +20,17 @@ import SwiftUI struct PhotoReasoningScreen: View { @StateObject var viewModel = PhotoReasoningViewModel() + enum FocusedField: Hashable { + case message + } + + @FocusState + var focusedField: FocusedField? + var body: some View { VStack { MultimodalInputField(text: $viewModel.userInput, selection: $viewModel.selectedItems) + .focused($focusedField, equals: .message) .onSubmit { onSendTapped() } @@ -47,11 +55,16 @@ struct PhotoReasoningScreen: View { } } .navigationTitle("Multimodal sample") + .onAppear { + focusedField = .message + } } // MARK: - Actions private func onSendTapped() { + focusedField = nil + Task { await viewModel.reason() } diff --git a/FirebaseVertexAI/Sample/GenerativeAIMultimodalSample/ViewModels/PhotoReasoningViewModel.swift b/FirebaseVertexAI/Sample/GenerativeAIMultimodalSample/ViewModels/PhotoReasoningViewModel.swift index dc41e00444a..ec0f3a7c6b3 100644 --- a/FirebaseVertexAI/Sample/GenerativeAIMultimodalSample/ViewModels/PhotoReasoningViewModel.swift +++ b/FirebaseVertexAI/Sample/GenerativeAIMultimodalSample/ViewModels/PhotoReasoningViewModel.swift @@ -44,7 +44,7 @@ class PhotoReasoningViewModel: ObservableObject { private var model: GenerativeModel? init() { - model = VertexAI.generativeModel(modelName: "gemini-1.0-pro-vision", location: "us-central1") + model = VertexAI.vertexAI().generativeModel(modelName: "gemini-1.5-flash-preview-0514") } func reason() async { diff --git a/FirebaseVertexAI/Sample/GenerativeAISample.xcodeproj/project.pbxproj b/FirebaseVertexAI/Sample/GenerativeAISample.xcodeproj/project.pbxproj deleted file mode 100644 index 20f07a5acca..00000000000 --- a/FirebaseVertexAI/Sample/GenerativeAISample.xcodeproj/project.pbxproj +++ /dev/null @@ -1,1053 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 60; - objects = { - -/* Begin PBXBuildFile section */ - 869200AB2B86BE3100482873 /* FirebaseVertexAI in Frameworks */ = {isa = PBXBuildFile; productRef = 869200AA2B86BE3100482873 /* FirebaseVertexAI */; }; - 869200AD2B86BEA100482873 /* FirebaseVertexAI in Frameworks */ = {isa = PBXBuildFile; productRef = 869200AC2B86BEA100482873 /* FirebaseVertexAI */; }; - 869200AF2B86BFBC00482873 /* FirebaseVertexAI in Frameworks */ = {isa = PBXBuildFile; productRef = 869200AE2B86BFBC00482873 /* FirebaseVertexAI */; }; - 869200B12B86BFF500482873 /* FirebaseVertexAI in Frameworks */ = {isa = PBXBuildFile; productRef = 869200B02B86BFF500482873 /* FirebaseVertexAI */; }; - 869200B32B879C4F00482873 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 869200B22B879C4F00482873 /* GoogleService-Info.plist */; }; - 869200B42B879C4F00482873 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 869200B22B879C4F00482873 /* GoogleService-Info.plist */; }; - 869200B52B879C4F00482873 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 869200B22B879C4F00482873 /* GoogleService-Info.plist */; }; - 869200B62B879C4F00482873 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 869200B22B879C4F00482873 /* GoogleService-Info.plist */; }; - 880266762B0FC39000CF7CB6 /* PhotoReasoningViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8802666F2B0FC39000CF7CB6 /* PhotoReasoningViewModel.swift */; }; - 880266792B0FC39000CF7CB6 /* PhotoReasoningScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 880266752B0FC39000CF7CB6 /* PhotoReasoningScreen.swift */; }; - 88209C1F2B0FBDC300F64795 /* SummarizeScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88209C1B2B0FBDC300F64795 /* SummarizeScreen.swift */; }; - 88209C202B0FBDC300F64795 /* SummarizeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88209C1D2B0FBDC300F64795 /* SummarizeViewModel.swift */; }; - 88209C242B0FBE1700F64795 /* MarkdownUI in Frameworks */ = {isa = PBXBuildFile; productRef = 88209C232B0FBE1700F64795 /* MarkdownUI */; }; - 88263BEF2B239BFE008AB09B /* ErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88263BEE2B239BFE008AB09B /* ErrorView.swift */; }; - 88263BF02B239C09008AB09B /* ErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88263BEE2B239BFE008AB09B /* ErrorView.swift */; }; - 88263BF12B239C11008AB09B /* ErrorDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 889873842B208563005B4896 /* ErrorDetailsView.swift */; }; - 8848C8332B0D04BC007B434F /* GenerativeAISampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8848C8322B0D04BC007B434F /* GenerativeAISampleApp.swift */; }; - 8848C8352B0D04BC007B434F /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8848C8342B0D04BC007B434F /* ContentView.swift */; }; - 8848C8372B0D04BD007B434F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8848C8362B0D04BD007B434F /* Assets.xcassets */; }; - 8848C83A2B0D04BD007B434F /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8848C8392B0D04BD007B434F /* Preview Assets.xcassets */; }; - 8848C8472B0D051E007B434F /* GenerativeAITextSampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8848C8462B0D051E007B434F /* GenerativeAITextSampleApp.swift */; }; - 8848C84B2B0D051F007B434F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8848C84A2B0D051F007B434F /* Assets.xcassets */; }; - 8848C84E2B0D051F007B434F /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8848C84D2B0D051F007B434F /* Preview Assets.xcassets */; }; - 8848C8592B0D056C007B434F /* GenerativeAIMultimodalSampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8848C8582B0D056C007B434F /* GenerativeAIMultimodalSampleApp.swift */; }; - 8848C85D2B0D056D007B434F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8848C85C2B0D056D007B434F /* Assets.xcassets */; }; - 8848C8602B0D056D007B434F /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8848C85F2B0D056D007B434F /* Preview Assets.xcassets */; }; - 886F95D52B17BA010036F07A /* SummarizeScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88209C1B2B0FBDC300F64795 /* SummarizeScreen.swift */; }; - 886F95D62B17BA010036F07A /* SummarizeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88209C1D2B0FBDC300F64795 /* SummarizeViewModel.swift */; }; - 886F95D82B17BA420036F07A /* MarkdownUI in Frameworks */ = {isa = PBXBuildFile; productRef = 886F95D72B17BA420036F07A /* MarkdownUI */; }; - 886F95DB2B17BAEF0036F07A /* PhotoReasoningViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8802666F2B0FC39000CF7CB6 /* PhotoReasoningViewModel.swift */; }; - 886F95DC2B17BAEF0036F07A /* PhotoReasoningScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 880266752B0FC39000CF7CB6 /* PhotoReasoningScreen.swift */; }; - 886F95DD2B17D5010036F07A /* MessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88E10F5A2B11133E00C08E95 /* MessageView.swift */; }; - 886F95DE2B17D5010036F07A /* ChatMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88E10F582B11131900C08E95 /* ChatMessage.swift */; }; - 886F95DF2B17D5010036F07A /* BouncingDots.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88E10F5C2B11135000C08E95 /* BouncingDots.swift */; }; - 886F95E02B17D5010036F07A /* ConversationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88E10F562B1112F600C08E95 /* ConversationViewModel.swift */; }; - 886F95E12B17D5010036F07A /* ConversationScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88E10F542B1112CA00C08E95 /* ConversationScreen.swift */; }; - 886F95E32B17D6630036F07A /* GenerativeAIUIComponents in Frameworks */ = {isa = PBXBuildFile; productRef = 886F95E22B17D6630036F07A /* GenerativeAIUIComponents */; }; - 889873852B208563005B4896 /* ErrorDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 889873842B208563005B4896 /* ErrorDetailsView.swift */; }; - 88B8A91E2B0FC55100424728 /* MarkdownUI in Frameworks */ = {isa = PBXBuildFile; productRef = 88B8A91D2B0FC55100424728 /* MarkdownUI */; }; - 88B8A9372B0FCBE700424728 /* GenerativeAIUIComponents in Frameworks */ = {isa = PBXBuildFile; productRef = 88B8A9362B0FCBE700424728 /* GenerativeAIUIComponents */; }; - 88D9474D2B14F27E008B5580 /* MarkdownUI in Frameworks */ = {isa = PBXBuildFile; productRef = 88D9474C2B14F27E008B5580 /* MarkdownUI */; }; - 88E10F452B110D5300C08E95 /* ChatSampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88E10F442B110D5300C08E95 /* ChatSampleApp.swift */; }; - 88E10F492B110D5400C08E95 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 88E10F482B110D5400C08E95 /* Assets.xcassets */; }; - 88E10F4C2B110D5400C08E95 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 88E10F4B2B110D5400C08E95 /* Preview Assets.xcassets */; }; - 88E10F552B1112CA00C08E95 /* ConversationScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88E10F542B1112CA00C08E95 /* ConversationScreen.swift */; }; - 88E10F572B1112F600C08E95 /* ConversationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88E10F562B1112F600C08E95 /* ConversationViewModel.swift */; }; - 88E10F592B11131900C08E95 /* ChatMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88E10F582B11131900C08E95 /* ChatMessage.swift */; }; - 88E10F5B2B11133E00C08E95 /* MessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88E10F5A2B11133E00C08E95 /* MessageView.swift */; }; - 88E10F5D2B11135000C08E95 /* BouncingDots.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88E10F5C2B11135000C08E95 /* BouncingDots.swift */; }; - CB0DFFD52B2B4F08006E109D /* GenerativeAIUIComponents in Frameworks */ = {isa = PBXBuildFile; productRef = CB0DFFD42B2B4F08006E109D /* GenerativeAIUIComponents */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 869200B22B879C4F00482873 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; - 8802666F2B0FC39000CF7CB6 /* PhotoReasoningViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoReasoningViewModel.swift; sourceTree = ""; }; - 880266752B0FC39000CF7CB6 /* PhotoReasoningScreen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoReasoningScreen.swift; sourceTree = ""; }; - 88209C1B2B0FBDC300F64795 /* SummarizeScreen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SummarizeScreen.swift; sourceTree = ""; }; - 88209C1D2B0FBDC300F64795 /* SummarizeViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SummarizeViewModel.swift; sourceTree = ""; }; - 88263BEE2B239BFE008AB09B /* ErrorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ErrorView.swift; sourceTree = ""; }; - 8848C82F2B0D04BC007B434F /* GenerativeAISample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GenerativeAISample.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 8848C8322B0D04BC007B434F /* GenerativeAISampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenerativeAISampleApp.swift; sourceTree = ""; }; - 8848C8342B0D04BC007B434F /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; - 8848C8362B0D04BD007B434F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 8848C8392B0D04BD007B434F /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; - 8848C8442B0D051E007B434F /* GenerativeAITextSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GenerativeAITextSample.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 8848C8462B0D051E007B434F /* GenerativeAITextSampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenerativeAITextSampleApp.swift; sourceTree = ""; }; - 8848C84A2B0D051F007B434F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 8848C84D2B0D051F007B434F /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; - 8848C8562B0D056C007B434F /* GenerativeAIMultimodalSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GenerativeAIMultimodalSample.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 8848C8582B0D056C007B434F /* GenerativeAIMultimodalSampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenerativeAIMultimodalSampleApp.swift; sourceTree = ""; }; - 8848C85C2B0D056D007B434F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 8848C85F2B0D056D007B434F /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; - 889873842B208563005B4896 /* ErrorDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorDetailsView.swift; sourceTree = ""; }; - 88B8A9352B0FCBA700424728 /* GenerativeAIUIComponents */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = GenerativeAIUIComponents; sourceTree = ""; }; - 88E10F422B110D5300C08E95 /* ChatSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ChatSample.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 88E10F442B110D5300C08E95 /* ChatSampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatSampleApp.swift; sourceTree = ""; }; - 88E10F482B110D5400C08E95 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 88E10F4B2B110D5400C08E95 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; - 88E10F542B1112CA00C08E95 /* ConversationScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationScreen.swift; sourceTree = ""; }; - 88E10F562B1112F600C08E95 /* ConversationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationViewModel.swift; sourceTree = ""; }; - 88E10F582B11131900C08E95 /* ChatMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessage.swift; sourceTree = ""; }; - 88E10F5A2B11133E00C08E95 /* MessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageView.swift; sourceTree = ""; }; - 88E10F5C2B11135000C08E95 /* BouncingDots.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BouncingDots.swift; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 8848C82C2B0D04BC007B434F /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 886F95D82B17BA420036F07A /* MarkdownUI in Frameworks */, - 869200AB2B86BE3100482873 /* FirebaseVertexAI in Frameworks */, - 886F95E32B17D6630036F07A /* GenerativeAIUIComponents in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8848C8412B0D051E007B434F /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 88209C242B0FBE1700F64795 /* MarkdownUI in Frameworks */, - 869200B12B86BFF500482873 /* FirebaseVertexAI in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8848C8532B0D056C007B434F /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 88B8A91E2B0FC55100424728 /* MarkdownUI in Frameworks */, - 869200AF2B86BFBC00482873 /* FirebaseVertexAI in Frameworks */, - 88B8A9372B0FCBE700424728 /* GenerativeAIUIComponents in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 88E10F3F2B110D5300C08E95 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 88D9474D2B14F27E008B5580 /* MarkdownUI in Frameworks */, - 869200AD2B86BEA100482873 /* FirebaseVertexAI in Frameworks */, - CB0DFFD52B2B4F08006E109D /* GenerativeAIUIComponents in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 8802666E2B0FC39000CF7CB6 /* ViewModels */ = { - isa = PBXGroup; - children = ( - 8802666F2B0FC39000CF7CB6 /* PhotoReasoningViewModel.swift */, - ); - path = ViewModels; - sourceTree = ""; - }; - 880266742B0FC39000CF7CB6 /* Screens */ = { - isa = PBXGroup; - children = ( - 880266752B0FC39000CF7CB6 /* PhotoReasoningScreen.swift */, - ); - path = Screens; - sourceTree = ""; - }; - 88209C1A2B0FBDC300F64795 /* Screens */ = { - isa = PBXGroup; - children = ( - 88209C1B2B0FBDC300F64795 /* SummarizeScreen.swift */, - ); - path = Screens; - sourceTree = ""; - }; - 88209C1C2B0FBDC300F64795 /* ViewModels */ = { - isa = PBXGroup; - children = ( - 88209C1D2B0FBDC300F64795 /* SummarizeViewModel.swift */, - ); - path = ViewModels; - sourceTree = ""; - }; - 88209C222B0FBE1700F64795 /* Frameworks */ = { - isa = PBXGroup; - children = ( - ); - name = Frameworks; - sourceTree = ""; - }; - 8848C8262B0D04BC007B434F = { - isa = PBXGroup; - children = ( - 88B8A9352B0FCBA700424728 /* GenerativeAIUIComponents */, - 869200B22B879C4F00482873 /* GoogleService-Info.plist */, - 8848C8312B0D04BC007B434F /* GenerativeAISample */, - 8848C8452B0D051E007B434F /* GenerativeAITextSample */, - 8848C8572B0D056C007B434F /* GenerativeAIMultimodalSample */, - 88E10F432B110D5300C08E95 /* ChatSample */, - 8848C8302B0D04BC007B434F /* Products */, - 88209C222B0FBE1700F64795 /* Frameworks */, - ); - sourceTree = ""; - }; - 8848C8302B0D04BC007B434F /* Products */ = { - isa = PBXGroup; - children = ( - 8848C82F2B0D04BC007B434F /* GenerativeAISample.app */, - 8848C8442B0D051E007B434F /* GenerativeAITextSample.app */, - 8848C8562B0D056C007B434F /* GenerativeAIMultimodalSample.app */, - 88E10F422B110D5300C08E95 /* ChatSample.app */, - ); - name = Products; - sourceTree = ""; - }; - 8848C8312B0D04BC007B434F /* GenerativeAISample */ = { - isa = PBXGroup; - children = ( - 8848C8322B0D04BC007B434F /* GenerativeAISampleApp.swift */, - 8848C8342B0D04BC007B434F /* ContentView.swift */, - 8848C8362B0D04BD007B434F /* Assets.xcassets */, - 8848C8382B0D04BD007B434F /* Preview Content */, - ); - path = GenerativeAISample; - sourceTree = ""; - }; - 8848C8382B0D04BD007B434F /* Preview Content */ = { - isa = PBXGroup; - children = ( - 8848C8392B0D04BD007B434F /* Preview Assets.xcassets */, - ); - path = "Preview Content"; - sourceTree = ""; - }; - 8848C8452B0D051E007B434F /* GenerativeAITextSample */ = { - isa = PBXGroup; - children = ( - 88209C1C2B0FBDC300F64795 /* ViewModels */, - 88209C1A2B0FBDC300F64795 /* Screens */, - 8848C8462B0D051E007B434F /* GenerativeAITextSampleApp.swift */, - 8848C84A2B0D051F007B434F /* Assets.xcassets */, - 8848C84C2B0D051F007B434F /* Preview Content */, - ); - path = GenerativeAITextSample; - sourceTree = ""; - }; - 8848C84C2B0D051F007B434F /* Preview Content */ = { - isa = PBXGroup; - children = ( - 8848C84D2B0D051F007B434F /* Preview Assets.xcassets */, - ); - path = "Preview Content"; - sourceTree = ""; - }; - 8848C8572B0D056C007B434F /* GenerativeAIMultimodalSample */ = { - isa = PBXGroup; - children = ( - 8802666E2B0FC39000CF7CB6 /* ViewModels */, - 880266742B0FC39000CF7CB6 /* Screens */, - 8848C8582B0D056C007B434F /* GenerativeAIMultimodalSampleApp.swift */, - 8848C85C2B0D056D007B434F /* Assets.xcassets */, - 8848C85E2B0D056D007B434F /* Preview Content */, - ); - path = GenerativeAIMultimodalSample; - sourceTree = ""; - }; - 8848C85E2B0D056D007B434F /* Preview Content */ = { - isa = PBXGroup; - children = ( - 8848C85F2B0D056D007B434F /* Preview Assets.xcassets */, - ); - path = "Preview Content"; - sourceTree = ""; - }; - 88E10F432B110D5300C08E95 /* ChatSample */ = { - isa = PBXGroup; - children = ( - 88E10F522B11124A00C08E95 /* Models */, - 88E10F502B11123600C08E95 /* ViewModels */, - 88E10F512B11124100C08E95 /* Views */, - 88E10F532B1112B900C08E95 /* Screens */, - 88E10F442B110D5300C08E95 /* ChatSampleApp.swift */, - 88E10F482B110D5400C08E95 /* Assets.xcassets */, - 88E10F4A2B110D5400C08E95 /* Preview Content */, - ); - path = ChatSample; - sourceTree = ""; - }; - 88E10F4A2B110D5400C08E95 /* Preview Content */ = { - isa = PBXGroup; - children = ( - 88E10F4B2B110D5400C08E95 /* Preview Assets.xcassets */, - ); - path = "Preview Content"; - sourceTree = ""; - }; - 88E10F502B11123600C08E95 /* ViewModels */ = { - isa = PBXGroup; - children = ( - 88E10F562B1112F600C08E95 /* ConversationViewModel.swift */, - ); - path = ViewModels; - sourceTree = ""; - }; - 88E10F512B11124100C08E95 /* Views */ = { - isa = PBXGroup; - children = ( - 88263BEE2B239BFE008AB09B /* ErrorView.swift */, - 88E10F5A2B11133E00C08E95 /* MessageView.swift */, - 88E10F5C2B11135000C08E95 /* BouncingDots.swift */, - 889873842B208563005B4896 /* ErrorDetailsView.swift */, - ); - path = Views; - sourceTree = ""; - }; - 88E10F522B11124A00C08E95 /* Models */ = { - isa = PBXGroup; - children = ( - 88E10F582B11131900C08E95 /* ChatMessage.swift */, - ); - path = Models; - sourceTree = ""; - }; - 88E10F532B1112B900C08E95 /* Screens */ = { - isa = PBXGroup; - children = ( - 88E10F542B1112CA00C08E95 /* ConversationScreen.swift */, - ); - path = Screens; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 8848C82E2B0D04BC007B434F /* GenerativeAISample */ = { - isa = PBXNativeTarget; - buildConfigurationList = 8848C83D2B0D04BD007B434F /* Build configuration list for PBXNativeTarget "GenerativeAISample" */; - buildPhases = ( - 8848C82B2B0D04BC007B434F /* Sources */, - 8848C82C2B0D04BC007B434F /* Frameworks */, - 8848C82D2B0D04BC007B434F /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = GenerativeAISample; - packageProductDependencies = ( - 886F95D72B17BA420036F07A /* MarkdownUI */, - 886F95E22B17D6630036F07A /* GenerativeAIUIComponents */, - 869200AA2B86BE3100482873 /* FirebaseVertexAI */, - ); - productName = GenerativeAISample; - productReference = 8848C82F2B0D04BC007B434F /* GenerativeAISample.app */; - productType = "com.apple.product-type.application"; - }; - 8848C8432B0D051E007B434F /* GenerativeAITextSample */ = { - isa = PBXNativeTarget; - buildConfigurationList = 8848C84F2B0D051F007B434F /* Build configuration list for PBXNativeTarget "GenerativeAITextSample" */; - buildPhases = ( - 8848C8402B0D051E007B434F /* Sources */, - 8848C8412B0D051E007B434F /* Frameworks */, - 8848C8422B0D051E007B434F /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = GenerativeAITextSample; - packageProductDependencies = ( - 88209C232B0FBE1700F64795 /* MarkdownUI */, - 869200B02B86BFF500482873 /* FirebaseVertexAI */, - ); - productName = GenerativeAITextSample; - productReference = 8848C8442B0D051E007B434F /* GenerativeAITextSample.app */; - productType = "com.apple.product-type.application"; - }; - 8848C8552B0D056C007B434F /* GenerativeAIMultimodalSample */ = { - isa = PBXNativeTarget; - buildConfigurationList = 8848C8612B0D056D007B434F /* Build configuration list for PBXNativeTarget "GenerativeAIMultimodalSample" */; - buildPhases = ( - 8848C8522B0D056C007B434F /* Sources */, - 8848C8532B0D056C007B434F /* Frameworks */, - 8848C8542B0D056C007B434F /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = GenerativeAIMultimodalSample; - packageProductDependencies = ( - 88B8A91D2B0FC55100424728 /* MarkdownUI */, - 88B8A9362B0FCBE700424728 /* GenerativeAIUIComponents */, - 869200AE2B86BFBC00482873 /* FirebaseVertexAI */, - ); - productName = GenerativeAIMultimodalSample; - productReference = 8848C8562B0D056C007B434F /* GenerativeAIMultimodalSample.app */; - productType = "com.apple.product-type.application"; - }; - 88E10F412B110D5300C08E95 /* ChatSample */ = { - isa = PBXNativeTarget; - buildConfigurationList = 88E10F4F2B110D5400C08E95 /* Build configuration list for PBXNativeTarget "ChatSample" */; - buildPhases = ( - 88E10F3E2B110D5300C08E95 /* Sources */, - 88E10F3F2B110D5300C08E95 /* Frameworks */, - 88E10F402B110D5300C08E95 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = ChatSample; - packageProductDependencies = ( - 88D9474C2B14F27E008B5580 /* MarkdownUI */, - CB0DFFD42B2B4F08006E109D /* GenerativeAIUIComponents */, - 869200AC2B86BEA100482873 /* FirebaseVertexAI */, - ); - productName = ChatSample; - productReference = 88E10F422B110D5300C08E95 /* ChatSample.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 8848C8272B0D04BC007B434F /* Project object */ = { - isa = PBXProject; - attributes = { - BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1510; - LastUpgradeCheck = 1510; - TargetAttributes = { - 8848C82E2B0D04BC007B434F = { - CreatedOnToolsVersion = 15.1; - }; - 8848C8432B0D051E007B434F = { - CreatedOnToolsVersion = 15.1; - }; - 8848C8552B0D056C007B434F = { - CreatedOnToolsVersion = 15.1; - }; - 88E10F412B110D5300C08E95 = { - CreatedOnToolsVersion = 15.1; - }; - }; - }; - buildConfigurationList = 8848C82A2B0D04BC007B434F /* Build configuration list for PBXProject "GenerativeAISample" */; - compatibilityVersion = "Xcode 14.0"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 8848C8262B0D04BC007B434F; - packageReferences = ( - 88209C212B0FBDF700F64795 /* XCRemoteSwiftPackageReference "swift-markdown-ui" */, - DEA09AC32B1FCE22001962D9 /* XCRemoteSwiftPackageReference "NetworkImage" */, - 869200A92B86BE3100482873 /* XCLocalSwiftPackageReference "../.." */, - ); - productRefGroup = 8848C8302B0D04BC007B434F /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 8848C82E2B0D04BC007B434F /* GenerativeAISample */, - 8848C8432B0D051E007B434F /* GenerativeAITextSample */, - 8848C8552B0D056C007B434F /* GenerativeAIMultimodalSample */, - 88E10F412B110D5300C08E95 /* ChatSample */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 8848C82D2B0D04BC007B434F /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8848C83A2B0D04BD007B434F /* Preview Assets.xcassets in Resources */, - 8848C8372B0D04BD007B434F /* Assets.xcassets in Resources */, - 869200B32B879C4F00482873 /* GoogleService-Info.plist in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8848C8422B0D051E007B434F /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8848C84E2B0D051F007B434F /* Preview Assets.xcassets in Resources */, - 8848C84B2B0D051F007B434F /* Assets.xcassets in Resources */, - 869200B42B879C4F00482873 /* GoogleService-Info.plist in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8848C8542B0D056C007B434F /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8848C8602B0D056D007B434F /* Preview Assets.xcassets in Resources */, - 8848C85D2B0D056D007B434F /* Assets.xcassets in Resources */, - 869200B52B879C4F00482873 /* GoogleService-Info.plist in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 88E10F402B110D5300C08E95 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 88E10F4C2B110D5400C08E95 /* Preview Assets.xcassets in Resources */, - 88E10F492B110D5400C08E95 /* Assets.xcassets in Resources */, - 869200B62B879C4F00482873 /* GoogleService-Info.plist in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 8848C82B2B0D04BC007B434F /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 886F95DF2B17D5010036F07A /* BouncingDots.swift in Sources */, - 886F95DE2B17D5010036F07A /* ChatMessage.swift in Sources */, - 88263BF12B239C11008AB09B /* ErrorDetailsView.swift in Sources */, - 8848C8352B0D04BC007B434F /* ContentView.swift in Sources */, - 886F95D52B17BA010036F07A /* SummarizeScreen.swift in Sources */, - 8848C8332B0D04BC007B434F /* GenerativeAISampleApp.swift in Sources */, - 886F95E02B17D5010036F07A /* ConversationViewModel.swift in Sources */, - 886F95DD2B17D5010036F07A /* MessageView.swift in Sources */, - 886F95DC2B17BAEF0036F07A /* PhotoReasoningScreen.swift in Sources */, - 886F95DB2B17BAEF0036F07A /* PhotoReasoningViewModel.swift in Sources */, - 886F95E12B17D5010036F07A /* ConversationScreen.swift in Sources */, - 88263BF02B239C09008AB09B /* ErrorView.swift in Sources */, - 886F95D62B17BA010036F07A /* SummarizeViewModel.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8848C8402B0D051E007B434F /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 88209C1F2B0FBDC300F64795 /* SummarizeScreen.swift in Sources */, - 8848C8472B0D051E007B434F /* GenerativeAITextSampleApp.swift in Sources */, - 88209C202B0FBDC300F64795 /* SummarizeViewModel.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8848C8522B0D056C007B434F /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 880266762B0FC39000CF7CB6 /* PhotoReasoningViewModel.swift in Sources */, - 880266792B0FC39000CF7CB6 /* PhotoReasoningScreen.swift in Sources */, - 8848C8592B0D056C007B434F /* GenerativeAIMultimodalSampleApp.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 88E10F3E2B110D5300C08E95 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 88E10F5B2B11133E00C08E95 /* MessageView.swift in Sources */, - 88E10F572B1112F600C08E95 /* ConversationViewModel.swift in Sources */, - 88E10F552B1112CA00C08E95 /* ConversationScreen.swift in Sources */, - 88E10F592B11131900C08E95 /* ChatMessage.swift in Sources */, - 88E10F5D2B11135000C08E95 /* BouncingDots.swift in Sources */, - 88E10F452B110D5300C08E95 /* ChatSampleApp.swift in Sources */, - 88263BEF2B239BFE008AB09B /* ErrorView.swift in Sources */, - 889873852B208563005B4896 /* ErrorDetailsView.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 8848C83B2B0D04BD007B434F /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - 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_DOCUMENTATION_COMMENTS = YES; - 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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu17; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 16.0; - LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 8848C83C2B0D04BD007B434F /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - 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_DOCUMENTATION_COMMENTS = YES; - 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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu17; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 16.0; - LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 8848C83E2B0D04BD007B434F /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_ASSET_PATHS = "\"GenerativeAISample/Preview Content\""; - DEVELOPMENT_TEAM = ""; - ENABLE_PREVIEWS = YES; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.google.generativeai.GenerativeAISample; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 8848C83F2B0D04BD007B434F /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_ASSET_PATHS = "\"GenerativeAISample/Preview Content\""; - DEVELOPMENT_TEAM = ""; - ENABLE_PREVIEWS = YES; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.google.generativeai.GenerativeAISample; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; - 8848C8502B0D051F007B434F /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_ASSET_PATHS = "\"GenerativeAITextSample/Preview Content\""; - DEVELOPMENT_TEAM = ""; - ENABLE_PREVIEWS = YES; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - IPHONEOS_DEPLOYMENT_TARGET = 16.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.google.generativeai.GenerativeAITextSample; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 8848C8512B0D051F007B434F /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_ASSET_PATHS = "\"GenerativeAITextSample/Preview Content\""; - DEVELOPMENT_TEAM = ""; - ENABLE_PREVIEWS = YES; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - IPHONEOS_DEPLOYMENT_TARGET = 16.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.google.generativeai.GenerativeAITextSample; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; - 8848C8622B0D056D007B434F /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_ASSET_PATHS = "\"GenerativeAIMultimodalSample/Preview Content\""; - DEVELOPMENT_TEAM = ""; - ENABLE_PREVIEWS = YES; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - IPHONEOS_DEPLOYMENT_TARGET = 16.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.google.generativeai.GenerativeAIMultimodalSample; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 8848C8632B0D056D007B434F /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_ASSET_PATHS = "\"GenerativeAIMultimodalSample/Preview Content\""; - DEVELOPMENT_TEAM = ""; - ENABLE_PREVIEWS = YES; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - IPHONEOS_DEPLOYMENT_TARGET = 16.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.google.generativeai.GenerativeAIMultimodalSample; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; - 88E10F4D2B110D5400C08E95 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_ASSET_PATHS = "\"ChatSample/Preview Content\""; - DEVELOPMENT_TEAM = ""; - ENABLE_PREVIEWS = YES; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - IPHONEOS_DEPLOYMENT_TARGET = 16.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.google.generativeai.ChatSample; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 88E10F4E2B110D5400C08E95 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_ASSET_PATHS = "\"ChatSample/Preview Content\""; - DEVELOPMENT_TEAM = ""; - ENABLE_PREVIEWS = YES; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - IPHONEOS_DEPLOYMENT_TARGET = 16.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.google.generativeai.ChatSample; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 8848C82A2B0D04BC007B434F /* Build configuration list for PBXProject "GenerativeAISample" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 8848C83B2B0D04BD007B434F /* Debug */, - 8848C83C2B0D04BD007B434F /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 8848C83D2B0D04BD007B434F /* Build configuration list for PBXNativeTarget "GenerativeAISample" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 8848C83E2B0D04BD007B434F /* Debug */, - 8848C83F2B0D04BD007B434F /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 8848C84F2B0D051F007B434F /* Build configuration list for PBXNativeTarget "GenerativeAITextSample" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 8848C8502B0D051F007B434F /* Debug */, - 8848C8512B0D051F007B434F /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 8848C8612B0D056D007B434F /* Build configuration list for PBXNativeTarget "GenerativeAIMultimodalSample" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 8848C8622B0D056D007B434F /* Debug */, - 8848C8632B0D056D007B434F /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 88E10F4F2B110D5400C08E95 /* Build configuration list for PBXNativeTarget "ChatSample" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 88E10F4D2B110D5400C08E95 /* Debug */, - 88E10F4E2B110D5400C08E95 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - -/* Begin XCLocalSwiftPackageReference section */ - 869200A92B86BE3100482873 /* XCLocalSwiftPackageReference "../.." */ = { - isa = XCLocalSwiftPackageReference; - relativePath = ../..; - }; -/* End XCLocalSwiftPackageReference section */ - -/* Begin XCRemoteSwiftPackageReference section */ - 88209C212B0FBDF700F64795 /* XCRemoteSwiftPackageReference "swift-markdown-ui" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/gonzalezreal/swift-markdown-ui"; - requirement = { - kind = revision; - revision = 5df8a4adedd6ae4eb2455ef60ff75183984daeb8; - }; - }; - DEA09AC32B1FCE22001962D9 /* XCRemoteSwiftPackageReference "NetworkImage" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/gonzalezreal/NetworkImage"; - requirement = { - kind = revision; - revision = 7aff8d1b31148d32c5933d75557d42f6323ee3d1; - }; - }; -/* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - 869200AA2B86BE3100482873 /* FirebaseVertexAI */ = { - isa = XCSwiftPackageProductDependency; - productName = FirebaseVertexAI; - }; - 869200AC2B86BEA100482873 /* FirebaseVertexAI */ = { - isa = XCSwiftPackageProductDependency; - productName = FirebaseVertexAI; - }; - 869200AE2B86BFBC00482873 /* FirebaseVertexAI */ = { - isa = XCSwiftPackageProductDependency; - productName = FirebaseVertexAI; - }; - 869200B02B86BFF500482873 /* FirebaseVertexAI */ = { - isa = XCSwiftPackageProductDependency; - productName = FirebaseVertexAI; - }; - 88209C232B0FBE1700F64795 /* MarkdownUI */ = { - isa = XCSwiftPackageProductDependency; - package = 88209C212B0FBDF700F64795 /* XCRemoteSwiftPackageReference "swift-markdown-ui" */; - productName = MarkdownUI; - }; - 886F95D72B17BA420036F07A /* MarkdownUI */ = { - isa = XCSwiftPackageProductDependency; - package = 88209C212B0FBDF700F64795 /* XCRemoteSwiftPackageReference "swift-markdown-ui" */; - productName = MarkdownUI; - }; - 886F95E22B17D6630036F07A /* GenerativeAIUIComponents */ = { - isa = XCSwiftPackageProductDependency; - productName = GenerativeAIUIComponents; - }; - 88B8A91D2B0FC55100424728 /* MarkdownUI */ = { - isa = XCSwiftPackageProductDependency; - package = 88209C212B0FBDF700F64795 /* XCRemoteSwiftPackageReference "swift-markdown-ui" */; - productName = MarkdownUI; - }; - 88B8A9362B0FCBE700424728 /* GenerativeAIUIComponents */ = { - isa = XCSwiftPackageProductDependency; - productName = GenerativeAIUIComponents; - }; - 88D9474C2B14F27E008B5580 /* MarkdownUI */ = { - isa = XCSwiftPackageProductDependency; - package = 88209C212B0FBDF700F64795 /* XCRemoteSwiftPackageReference "swift-markdown-ui" */; - productName = MarkdownUI; - }; - CB0DFFD42B2B4F08006E109D /* GenerativeAIUIComponents */ = { - isa = XCSwiftPackageProductDependency; - productName = GenerativeAIUIComponents; - }; -/* End XCSwiftPackageProductDependency section */ - }; - rootObject = 8848C8272B0D04BC007B434F /* Project object */; -} diff --git a/FirebaseVertexAI/Sample/GenerativeAISample/GenerativeAISampleApp.swift b/FirebaseVertexAI/Sample/GenerativeAISample/GenerativeAISampleApp.swift deleted file mode 100644 index 7c709111b7f..00000000000 --- a/FirebaseVertexAI/Sample/GenerativeAISample/GenerativeAISampleApp.swift +++ /dev/null @@ -1,29 +0,0 @@ -// 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 FirebaseCore -import SwiftUI - -@main -struct GenerativeAISampleApp: App { - init() { - FirebaseApp.configure() - } - - var body: some Scene { - WindowGroup { - ContentView() - } - } -} diff --git a/FirebaseVertexAI/Sample/GenerativeAITextSample/GenerativeAITextSampleApp.swift b/FirebaseVertexAI/Sample/GenerativeAITextSample/GenerativeAITextSampleApp.swift deleted file mode 100644 index c800e1f7be8..00000000000 --- a/FirebaseVertexAI/Sample/GenerativeAITextSample/GenerativeAITextSampleApp.swift +++ /dev/null @@ -1,31 +0,0 @@ -// 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 FirebaseCore -import SwiftUI - -@main -struct GenerativeAITextSampleApp: App { - init() { - FirebaseApp.configure() - } - - var body: some Scene { - WindowGroup { - NavigationStack { - SummarizeScreen() - } - } - } -} diff --git a/FirebaseVertexAI/Sample/GenerativeAITextSample/Screens/SummarizeScreen.swift b/FirebaseVertexAI/Sample/GenerativeAITextSample/Screens/SummarizeScreen.swift index 8fbb89f4482..748c1addd5f 100644 --- a/FirebaseVertexAI/Sample/GenerativeAITextSample/Screens/SummarizeScreen.swift +++ b/FirebaseVertexAI/Sample/GenerativeAITextSample/Screens/SummarizeScreen.swift @@ -28,19 +28,23 @@ struct SummarizeScreen: View { var body: some View { VStack { - Text("Enter some text, then tap on _Go_ to summarize it.") - HStack(alignment: .top) { - TextField("Enter text summarize", text: $userInput, axis: .vertical) - .textFieldStyle(.roundedBorder) - .onSubmit { + VStack(alignment: .leading) { + Text("Enter some text, then tap on _Go_ to summarize it.") + .padding(.horizontal, 6) + HStack(alignment: .top) { + TextField("Enter text summarize", text: $userInput, axis: .vertical) + .focused($focusedField, equals: .message) + .textFieldStyle(.roundedBorder) + .onSubmit { + onSummarizeTapped() + } + Button("Go") { onSummarizeTapped() } - Button("Go") { - onSummarizeTapped() + .padding(.top, 4) } - .padding(.top, 4) } - .padding([.horizontal, .bottom]) + .padding(.horizontal, 16) List { HStack(alignment: .top) { @@ -61,6 +65,8 @@ struct SummarizeScreen: View { } private func onSummarizeTapped() { + focusedField = nil + Task { await viewModel.summarize(inputText: userInput) } diff --git a/FirebaseVertexAI/Sample/GenerativeAITextSample/ViewModels/SummarizeViewModel.swift b/FirebaseVertexAI/Sample/GenerativeAITextSample/ViewModels/SummarizeViewModel.swift index fb5b349ac82..77e815ea77d 100644 --- a/FirebaseVertexAI/Sample/GenerativeAITextSample/ViewModels/SummarizeViewModel.swift +++ b/FirebaseVertexAI/Sample/GenerativeAITextSample/ViewModels/SummarizeViewModel.swift @@ -32,7 +32,7 @@ class SummarizeViewModel: ObservableObject { private var model: GenerativeModel? init() { - model = VertexAI.generativeModel(modelName: "gemini-1.0-pro", location: "us-central1") + model = VertexAI.vertexAI().generativeModel(modelName: "gemini-1.5-flash-preview-0514") } func summarize(inputText: String) async { diff --git a/FirebaseVertexAI/Sample/GenerativeAIUIComponents/Sources/GenerativeAIUIComponents/InputField.swift b/FirebaseVertexAI/Sample/GenerativeAIUIComponents/Sources/GenerativeAIUIComponents/InputField.swift index 317baaaf3c1..67941c370cb 100644 --- a/FirebaseVertexAI/Sample/GenerativeAIUIComponents/Sources/GenerativeAIUIComponents/InputField.swift +++ b/FirebaseVertexAI/Sample/GenerativeAIUIComponents/Sources/GenerativeAIUIComponents/InputField.swift @@ -13,6 +13,7 @@ // limitations under the License. import SwiftUI + public struct InputField