From 9231dd0c99d3745ce4174b8c91acbbe93bfcdeb1 Mon Sep 17 00:00:00 2001 From: Russell Wheatley Date: Tue, 10 Dec 2024 10:22:16 +0000 Subject: [PATCH] feat(perf): Swift Package Manager support (#16849) --- .github/workflows/all_plugins.yaml | 2 +- .../workflows/scripts/swift-integration.dart | 3 +- .../example/ios/Flutter/Debug.xcconfig | 2 +- .../example/ios/Flutter/Release.xcconfig | 2 +- .../ios/firebase_performance.podspec | 6 +- .../ios/firebase_performance/Package.swift | 120 ++++++++++++++++++ .../FLTFirebasePerformancePlugin.m | 8 +- .../firebase_performance/Resources}/.gitkeep | 0 .../include}/FLTFirebasePerformancePlugin.h | 4 + .../ios/generated_firebase_sdk_version.txt | 1 + 10 files changed, 139 insertions(+), 9 deletions(-) create mode 100644 packages/firebase_performance/firebase_performance/ios/firebase_performance/Package.swift rename packages/firebase_performance/firebase_performance/ios/{Classes => firebase_performance/Sources/firebase_performance}/FLTFirebasePerformancePlugin.m (98%) rename packages/firebase_performance/firebase_performance/ios/{Assets => firebase_performance/Sources/firebase_performance/Resources}/.gitkeep (100%) rename packages/firebase_performance/firebase_performance/ios/{Classes => firebase_performance/Sources/firebase_performance/include}/FLTFirebasePerformancePlugin.h (80%) create mode 100644 packages/firebase_performance/firebase_performance/ios/generated_firebase_sdk_version.txt diff --git a/.github/workflows/all_plugins.yaml b/.github/workflows/all_plugins.yaml index f073c3c7a181..1b940ef30761 100644 --- a/.github/workflows/all_plugins.yaml +++ b/.github/workflows/all_plugins.yaml @@ -126,7 +126,7 @@ jobs: runs-on: macos-latest timeout-minutes: 30 env: - FLUTTER_DEPENDENCIES: "cloud_firestore firebase_remote_config cloud_functions firebase_database firebase_auth firebase_storage firebase_analytics firebase_messaging firebase_app_check firebase_in_app_messaging" + FLUTTER_DEPENDENCIES: "cloud_firestore firebase_remote_config cloud_functions firebase_database firebase_auth firebase_storage firebase_analytics firebase_messaging firebase_app_check firebase_in_app_messaging firebase_performance" steps: - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - uses: subosito/flutter-action@2783a3f08e1baf891508463f8c6653c258246225 diff --git a/.github/workflows/scripts/swift-integration.dart b/.github/workflows/scripts/swift-integration.dart index 14daeaee0a4f..b87f35ebfc26 100644 --- a/.github/workflows/scripts/swift-integration.dart +++ b/.github/workflows/scripts/swift-integration.dart @@ -20,7 +20,8 @@ Future buildSwiftExampleApp(String platform, String plugins) async { print('Building example app with swift (SPM) integration for $plugins'); - final directory = Directory('packages/firebase_core/firebase_core/example/$platform'); + final directory = + Directory('packages/firebase_core/firebase_core/example/$platform'); if (!directory.existsSync()) { print('Directory does not exist: ${directory.path}'); exit(1); diff --git a/packages/firebase_performance/firebase_performance/example/ios/Flutter/Debug.xcconfig b/packages/firebase_performance/firebase_performance/example/ios/Flutter/Debug.xcconfig index e8efba114687..ec97fc6f3021 100644 --- a/packages/firebase_performance/firebase_performance/example/ios/Flutter/Debug.xcconfig +++ b/packages/firebase_performance/firebase_performance/example/ios/Flutter/Debug.xcconfig @@ -1,2 +1,2 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/packages/firebase_performance/firebase_performance/example/ios/Flutter/Release.xcconfig b/packages/firebase_performance/firebase_performance/example/ios/Flutter/Release.xcconfig index 399e9340e6f6..c4855bfe2000 100644 --- a/packages/firebase_performance/firebase_performance/example/ios/Flutter/Release.xcconfig +++ b/packages/firebase_performance/firebase_performance/example/ios/Flutter/Release.xcconfig @@ -1,2 +1,2 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/packages/firebase_performance/firebase_performance/ios/firebase_performance.podspec b/packages/firebase_performance/firebase_performance/ios/firebase_performance.podspec index 43c66340d4fb..9098bf31ff5d 100644 --- a/packages/firebase_performance/firebase_performance/ios/firebase_performance.podspec +++ b/packages/firebase_performance/firebase_performance/ios/firebase_performance.podspec @@ -27,8 +27,8 @@ Pod::Spec.new do |s| s.license = { :file => '../LICENSE' } s.authors = 'The Chromium Authors' s.source = { :path => '.' } - s.source_files = 'Classes/**/*' - s.public_header_files = 'Classes/**/*.h' + s.source_files = 'firebase_performance/Sources/firebase_performance/**/*.{h,m}' + s.public_header_files = 'firebase_performance/Sources/firebase_performance/include/*.h' s.dependency 'Flutter' s.dependency 'firebase_core' s.dependency 'Firebase/Performance', firebase_sdk_version @@ -36,7 +36,7 @@ Pod::Spec.new do |s| s.static_framework = true s.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => "LIBRARY_VERSION=\\@\\\"#{library_version}\\\" LIBRARY_NAME=\\@\\\"flutter-fire-perf\\\"", + 'GCC_PREPROCESSOR_DEFINITIONS' => "LIBRARY_VERSION=\\\"#{library_version}\\\" LIBRARY_NAME=\\\"flutter-fire-perf\\\"", 'DEFINES_MODULE' => 'YES' } end diff --git a/packages/firebase_performance/firebase_performance/ios/firebase_performance/Package.swift b/packages/firebase_performance/firebase_performance/ios/firebase_performance/Package.swift new file mode 100644 index 000000000000..9c420549c475 --- /dev/null +++ b/packages/firebase_performance/firebase_performance/ios/firebase_performance/Package.swift @@ -0,0 +1,120 @@ +// swift-tools-version: 5.9 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +// Copyright 2024, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import Foundation +import PackageDescription + +enum ConfigurationError: Error { + case fileNotFound(String) + case parsingError(String) + case invalidFormat(String) +} + +let performanceDirectory = String(URL(string: #file)!.deletingLastPathComponent().absoluteString + .dropLast()) + +func loadFirebaseSDKVersion() throws -> String { + let firebaseCoreScriptPath = NSString.path(withComponents: [ + performanceDirectory, + "..", + "generated_firebase_sdk_version.txt", + ]) + do { + let version = try String(contentsOfFile: firebaseCoreScriptPath, encoding: .utf8) + .trimmingCharacters(in: .whitespacesAndNewlines) + return version + } catch { + throw ConfigurationError + .fileNotFound("Error loading or parsing generated_firebase_sdk_version.txt: \(error)") + } +} + +func loadPubspecVersions() throws -> (packageVersion: String, firebaseCoreVersion: String) { + let pubspecPath = NSString.path(withComponents: [ + performanceDirectory, + "..", + "..", + "pubspec.yaml", + ]) + do { + let yamlString = try String(contentsOfFile: pubspecPath, encoding: .utf8) + let lines = yamlString.split(separator: "\n") + + guard let packageVersionLine = lines.first(where: { $0.starts(with: "version:") }) else { + throw ConfigurationError.invalidFormat("No package version line found in pubspec.yaml") + } + var packageVersion = packageVersionLine.split(separator: ":")[1] + .trimmingCharacters(in: .whitespaces) + .replacingOccurrences(of: "+", with: "-") + packageVersion = packageVersion.replacingOccurrences(of: "^", with: "") + + guard let firebaseCoreVersionLine = lines.first(where: { $0.contains("firebase_core:") }) else { + throw ConfigurationError + .invalidFormat("No firebase_core dependency version line found in pubspec.yaml") + } + var firebaseCoreVersion = firebaseCoreVersionLine.split(separator: ":")[1] + .trimmingCharacters(in: .whitespaces) + firebaseCoreVersion = firebaseCoreVersion.replacingOccurrences(of: "^", with: "") + + return (packageVersion, firebaseCoreVersion) + } catch { + throw ConfigurationError.fileNotFound("Error loading or parsing pubspec.yaml: \(error)") + } +} + +let library_version: String +let firebase_sdk_version_string: String +let firebase_core_version_string: String +let shared_spm_tag = "-firebase-core-swift" + +do { + library_version = try loadPubspecVersions().packageVersion + firebase_sdk_version_string = try loadFirebaseSDKVersion() + firebase_core_version_string = try loadPubspecVersions().firebaseCoreVersion +} catch { + fatalError("Failed to load configuration: \(error)") +} + +guard let firebase_sdk_version = Version(firebase_sdk_version_string) else { + fatalError("Invalid Firebase SDK version: \(firebase_sdk_version_string)") +} + +guard let shared_spm_version = Version("\(firebase_core_version_string)\(shared_spm_tag)") else { + fatalError("Invalid firebase_core version: \(firebase_core_version_string)\(shared_spm_tag)") +} + +let package = Package( + name: "firebase_performance", + platforms: [ + .iOS("13.0"), + ], + products: [ + .library(name: "firebase-performance", targets: ["firebase_performance"]), + ], + dependencies: [ + .package(url: "https://github.com/firebase/firebase-ios-sdk", from: firebase_sdk_version), + .package(url: "https://github.com/firebase/flutterfire", exact: shared_spm_version), + ], + targets: [ + .target( + name: "firebase_performance", + dependencies: [ + .product(name: "FirebasePerformance", package: "firebase-ios-sdk"), + // Wrapper dependency + .product(name: "firebase-core-shared", package: "flutterfire"), + ], + resources: [ + .process("Resources"), + ], + cSettings: [ + .headerSearchPath("include"), + .define("LIBRARY_VERSION", to: "\"\(library_version)\""), + .define("LIBRARY_NAME", to: "\"flutter-fire-perf\""), + ] + ), + ] +) diff --git a/packages/firebase_performance/firebase_performance/ios/Classes/FLTFirebasePerformancePlugin.m b/packages/firebase_performance/firebase_performance/ios/firebase_performance/Sources/firebase_performance/FLTFirebasePerformancePlugin.m similarity index 98% rename from packages/firebase_performance/firebase_performance/ios/Classes/FLTFirebasePerformancePlugin.m rename to packages/firebase_performance/firebase_performance/ios/firebase_performance/Sources/firebase_performance/FLTFirebasePerformancePlugin.m index c5918253a5b8..3a19f69846a6 100644 --- a/packages/firebase_performance/firebase_performance/ios/Classes/FLTFirebasePerformancePlugin.m +++ b/packages/firebase_performance/firebase_performance/ios/firebase_performance/Sources/firebase_performance/FLTFirebasePerformancePlugin.m @@ -4,7 +4,11 @@ #import "FLTFirebasePerformancePlugin.h" +#if __has_include() #import +#else +#import +#endif NSString *const kFLTFirebasePerformanceChannelName = @"plugins.flutter.io/firebase_performance"; @@ -214,11 +218,11 @@ - (NSDictionary *_Nonnull)pluginConstantsForFIRApp:(FIRApp *)firebase_app { } - (NSString *_Nonnull)firebaseLibraryName { - return LIBRARY_NAME; + return @LIBRARY_NAME; } - (NSString *_Nonnull)firebaseLibraryVersion { - return LIBRARY_VERSION; + return @LIBRARY_VERSION; } - (NSString *_Nonnull)flutterChannelName { diff --git a/packages/firebase_performance/firebase_performance/ios/Assets/.gitkeep b/packages/firebase_performance/firebase_performance/ios/firebase_performance/Sources/firebase_performance/Resources/.gitkeep similarity index 100% rename from packages/firebase_performance/firebase_performance/ios/Assets/.gitkeep rename to packages/firebase_performance/firebase_performance/ios/firebase_performance/Sources/firebase_performance/Resources/.gitkeep diff --git a/packages/firebase_performance/firebase_performance/ios/Classes/FLTFirebasePerformancePlugin.h b/packages/firebase_performance/firebase_performance/ios/firebase_performance/Sources/firebase_performance/include/FLTFirebasePerformancePlugin.h similarity index 80% rename from packages/firebase_performance/firebase_performance/ios/Classes/FLTFirebasePerformancePlugin.h rename to packages/firebase_performance/firebase_performance/ios/firebase_performance/Sources/firebase_performance/include/FLTFirebasePerformancePlugin.h index 72bfa30eea03..65b30ab94a1b 100644 --- a/packages/firebase_performance/firebase_performance/ios/Classes/FLTFirebasePerformancePlugin.h +++ b/packages/firebase_performance/firebase_performance/ios/firebase_performance/Sources/firebase_performance/include/FLTFirebasePerformancePlugin.h @@ -5,7 +5,11 @@ @import FirebasePerformance; #import #import +#if __has_include() #import +#else +#import +#endif @interface FLTFirebasePerformancePlugin : FLTFirebasePlugin diff --git a/packages/firebase_performance/firebase_performance/ios/generated_firebase_sdk_version.txt b/packages/firebase_performance/firebase_performance/ios/generated_firebase_sdk_version.txt new file mode 100644 index 000000000000..72773deb895e --- /dev/null +++ b/packages/firebase_performance/firebase_performance/ios/generated_firebase_sdk_version.txt @@ -0,0 +1 @@ +11.4.0