Skip to content

Commit

Permalink
feat(crashlytics): Swift Package Manager support (#16811)
Browse files Browse the repository at this point in the history
  • Loading branch information
russellwheatley authored Dec 10, 2024
1 parent 4d91fd8 commit f7cd1ab
Show file tree
Hide file tree
Showing 24 changed files with 311 additions and 125 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/all_plugins.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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 firebase_performance firebase_dynamic_links"
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 firebase_dynamic_links firebase_crashlytics"
steps:
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
- uses: subosito/flutter-action@2783a3f08e1baf891508463f8c6653c258246225
Expand Down
Original file line number Diff line number Diff line change
@@ -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"
Original file line number Diff line number Diff line change
@@ -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"
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; };
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
A12DFD83E7CB055B40E187D8 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D55BC6AF721FE0A09D114460 /* Pods_Runner.framework */; };
AAE9D7BFA8AAA8783C2860B2 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 864CBEC4F3EDA362F4B5B76D /* GoogleService-Info.plist */; };
/* End PBXBuildFile section */

Expand All @@ -35,9 +35,7 @@
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3483EF1253077C699E331BE4 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
76260442B9364E9433AC028C /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
Expand All @@ -50,16 +48,14 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
D14C8104C6F6DBC16421D2F4 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
D55BC6AF721FE0A09D114460 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
A12DFD83E7CB055B40E187D8 /* Pods_Runner.framework in Frameworks */,
78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -69,21 +65,10 @@
578F13DB49C24452CA02A630 /* Pods */ = {
isa = PBXGroup;
children = (
76260442B9364E9433AC028C /* Pods-Runner.debug.xcconfig */,
D14C8104C6F6DBC16421D2F4 /* Pods-Runner.release.xcconfig */,
3483EF1253077C699E331BE4 /* Pods-Runner.profile.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
};
9278C72542532A6D4853596F /* Frameworks */ = {
isa = PBXGroup;
children = (
D55BC6AF721FE0A09D114460 /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
Expand All @@ -102,7 +87,6 @@
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
578F13DB49C24452CA02A630 /* Pods */,
9278C72542532A6D4853596F /* Frameworks */,
864CBEC4F3EDA362F4B5B76D /* GoogleService-Info.plist */,
);
sourceTree = "<group>";
Expand Down Expand Up @@ -146,21 +130,22 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
FF93E33FF58D2AD673D0393E /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
324E062721E4156B000CBB4D /* ShellScript */,
4C5E378AEFE70180B5AB5AE0 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
packageProductDependencies = (
78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */,
);
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
Expand Down Expand Up @@ -190,6 +175,9 @@
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
packageReferences = (
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */,
);
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
Expand Down Expand Up @@ -249,44 +237,6 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
4C5E378AEFE70180B5AB5AE0 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/FirebaseCore/FirebaseCore.framework",
"${BUILT_PRODUCTS_DIR}/FirebaseCoreExtension/FirebaseCoreExtension.framework",
"${BUILT_PRODUCTS_DIR}/FirebaseCoreInternal/FirebaseCoreInternal.framework",
"${BUILT_PRODUCTS_DIR}/FirebaseCrashlytics/FirebaseCrashlytics.framework",
"${BUILT_PRODUCTS_DIR}/FirebaseInstallations/FirebaseInstallations.framework",
"${BUILT_PRODUCTS_DIR}/FirebaseSessions/FirebaseSessions.framework",
"${BUILT_PRODUCTS_DIR}/GoogleDataTransport/GoogleDataTransport.framework",
"${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework",
"${BUILT_PRODUCTS_DIR}/PromisesObjC/FBLPromises.framework",
"${BUILT_PRODUCTS_DIR}/PromisesSwift/Promises.framework",
"${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCore.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCoreExtension.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCoreInternal.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCrashlytics.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseInstallations.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseSessions.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleDataTransport.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBLPromises.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Promises.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
Expand All @@ -302,28 +252,6 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
};
FF93E33FF58D2AD673D0393E /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
Expand Down Expand Up @@ -613,6 +541,20 @@
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */

/* Begin XCLocalSwiftPackageReference section */
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */ = {
isa = XCLocalSwiftPackageReference;
relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage;
};
/* End XCLocalSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = {
isa = XCSwiftPackageProductDependency;
productName = FlutterGeneratedPluginSwiftPackage;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,24 @@
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<PreActions>
<ExecutionAction
ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
<ActionContent
title = "Run Prepare Flutter Framework Script"
scriptText = "/bin/sh &quot;$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh&quot; prepare&#10;">
<EnvironmentBuildable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</EnvironmentBuildable>
</ActionContent>
</ExecutionAction>
</PreActions>
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ Pod::Spec.new do |s|
s.authors = 'The Chromium Authors'
s.source = { :path => '.' }

s.source_files = 'Classes/**/*'
s.public_header_files = 'Classes/**/*.h'
s.source_files = 'firebase_crashlytics/Sources/firebase_crashlytics/**/*.{h,m}'
s.public_header_files = 'firebase_crashlytics/Sources/firebase_crashlytics/include/*.h'

s.ios.deployment_target = '13.0'

Expand All @@ -42,7 +42,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-cls\\\"",
'GCC_PREPROCESSOR_DEFINITIONS' => "LIBRARY_VERSION=\\\"#{library_version}\\\" LIBRARY_NAME=\\\"flutter-fire-cls\\\"",
'DEFINES_MODULE' => 'YES'
}
s.user_target_xcconfig = { 'DEBUG_INFORMATION_FORMAT' => 'dwarf-with-dsym' }
Expand Down
Original file line number Diff line number Diff line change
@@ -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 crashlyticsDirectory = String(URL(string: #file)!.deletingLastPathComponent().absoluteString
.dropLast())

func loadFirebaseSDKVersion() throws -> String {
let firebaseCoreScriptPath = NSString.path(withComponents: [
crashlyticsDirectory,
"..",
"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: [
crashlyticsDirectory,
"..",
"..",
"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_crashlytics",
platforms: [
.iOS("13.0"),
],
products: [
.library(name: "firebase-crashlytics", targets: ["firebase_crashlytics"]),
],
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_crashlytics",
dependencies: [
.product(name: "FirebaseCrashlytics", 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-cls\""),
]
),
]
)
Loading

0 comments on commit f7cd1ab

Please sign in to comment.