firebase / firebase/firebase-ios-sdk
SwiftUI Previews fail with JIT runtime linking failure (`_APM*` symbols not found) since 12.15.0 when FirebaseAnalytics is used in a Swift package static library target
- Dominant language
- C++
- Stars
- 6.7k
- Forks
- 1.8k
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 73
Description
### Description
Since firebase-ios-sdk 12.15.0, Xcode's SwiftUI Previews fail to render any view that (transitively) uses `View.analyticsScreen(...)` when `FirebaseAnalytics` is a dependency of a static library target in a Swift package. The preview agent's JIT linker reports `Runtime linking failure` with 16 `_APM*` symbols from GoogleAppMeasurement not found.
- **12.14.0: the same preview renders fine.** 12.15.0, 12.16.0, and 12.17.0 all fail with the identical error (each verified with the minimal repro below), so this is a regression introduced in 12.15.0 and still present in the latest release.
- Only Previews are affected. Regular builds and runs on simulator and device work fine on all versions.
- **Workaround (verified):** declaring the package product as `.library(type: .dynamic, ...)` makes the same preview render successfully on 12.17.0. The failure only occurs on the static linking path of the Previews JIT.
- GoogleAdsOnDeviceConversion resolves to the same version (3.6.1) in both the working (12.14.0) and failing (12.15.0+) configurations, so this is not the same cause as #16070.
I compared the 12.14.0 and 12.15.0+ binaries to narrow this down, and could not find a structural difference that explains it:
- All 16 missing symbols are globally defined (`nm` types `S`/`T`) in the `ios-arm64_x86_64-simulator` slice of `GoogleAppMeasurement.xcframework` in every version from 12.14.0 through 12.17.0, and all 16 are listed in the archive's ranlib table (`llvm-nm --print-armap`)
- The archive member list (369 members, all Mach-O objects, no LTO bitcode) is identical across versions, and the objects target the same SDK (`LC_BUILD_VERSION`: minos 15.0, sdk 26.2)
- `FirebaseAnalytics.xcframework`'s member list, undefined `_APM*` references (34), and `.swiftinterface` text are also identical between 12.14.0 and 12.15.0
So whatever changed in the 12.15.0 binaries is below the symbol-table level, but it flips the Previews JIT linker from resolving these symbols to not finding them.
Expected: the preview renders, as it does with 12.14.0.
Actual: `PreviewFailedError` with the JIT error below.
### Reproducing the issue
Minimal reproducible example: https://github.com/y-hakutaku/firebase-analytics-preview-repro
The repro is a single Swift package with one static library target that depends on `FirebaseAnalytics` and contains one `ViewModifier` calling `.analyticsScreen(name:)` plus a `#Preview`.
1. Clone the repo and open `Package.swift` in Xcode, wait for package resolution
2. Open `Sources/AnalyticsUI/TrackedScreenModifier.swift`
3. Show the Canvas (⌥⌘↩) and let the `#Preview` build → it fails with the error below
4. Change the dependency to `exact: "12.14.0"` in `Package.swift` → the same preview renders successfully
5. (Workaround check) Restore 12.17.0 and declare the product as `.library(name: "AnalyticsUIModule", type: .dynamic, targets: ["AnalyticsUI"])` → the preview renders successfully
Environment used for verification: Xcode 26.6 (17F113) on macOS 26.3.1 (Apple silicon), previewing on an iPhone simulator run destination. Also reproduced from a clean clone with fresh DerivedData.
### Firebase SDK Version
12.15.0–12.17.0 (12.14.0 works)
### Xcode Version
26.6 (17F113)
### Installation Method
Swift Package Manager
### Firebase Product(s)
Analytics
### Targeted Platforms
iOS
### Relevant Log Output
```shell
PreviewFailedError: Preview errored.
==================================
| EvolvingError
|
| EvolvingError: EvolvingError(initialError: [Remote] JITError: Runtime linking failure
|
| Additional Link Time Errors:
| Symbols not found: [ _APMIsAnalyticsCollectionDeactivated, _APMAppMeasurementOriginFirebase, _OBJC_CLASS_$_APMIdentity, _OBJC_CLASS_$_APMMeasurement, _APMUserDataFieldHashedPhoneNumber, _APMConsentSettings3P, _APMFormattedEventName, _APMIsValidTransactionDeviceVerification, _APMUserDataFieldEmailAddress, _OBJC_CLASS_$_APMAnalytics, _APMMonitorLogTagOptionKey, _APMUserDataFieldHashedEmailAddress, _APMAnalyticsConfiguration, _APMUserDataFieldPhoneNumber, _APMIsAnalyticsCollectionEnabled, _APMFormattedUserPropertyName ]
|
| ==================================
|
| | [Remote] LLVMError
| |
| | LLVMError: LLVMError(description: "Failed to materialize symbols: { (static-AnalyticsUI, { ___swift_instantiateConcreteTypeFromMangledNameAbstractV2$5$body, _$s11AnalyticsUI04$s11A116UI0032TrackedScreenModifierswift_jIADjfMX25_0_33_A1EB42AD39FCA07F1947DF219D89115DLl7PreviewfMf_15PreviewRegistryfMu_V04makeT021DeveloperToolsSupport0T0VyKFZ05SwiftB04View_pyScMYccfU_$5$body, ... (truncated; the full list is every symbol in the previewed file's object) ... } }"), evolutions: nil)
```
### If using Swift Package Manager, the project's Package.resolved
Expand Package.resolved snippet
```json
{
"originHash" : "6106fd095c36d994a2c43095bb4b3f25b294113ae1fcbb3287e730437a6baab7",
"pins" : [
{
"identity" : "abseil-cpp-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/abseil-cpp-binary.git",
"state" : {
"revision" : "bbe8b69694d7873315fd3a4ad41efe043e1c07c5",
"version" : "1.2024072200.0"
}
},
{
"identity" : "app-check",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/app-check.git",
"state" : {
"revision" : "3e33dd27dd4c69bd81c7c81fe61d8ccf58846902",
"version" : "11.3.1"
}
},
{
"identity" : "firebase-ios-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/firebase-ios-sdk.git",
"state" : {
"revision" : "33a468adfdb75b53f05a37e7c886ca7c962b5c17",
"version" : "12.17.0"
}
},
{
"identity" : "google-ads-on-device-conversion-ios-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/googleads/google-ads-on-device-conversion-ios-sdk",
"state" : {
"revision" : "dc39082d8881109d35b94b1c122164c0e8d08a55",
"version" : "3.6.1"
}
},
{
"identity" : "googleappmeasurement",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleAppMeasurement.git",
"state" : {
"revision" : "fceaffa07d22dcd5624d3639fd970351a4a5ad8c",
"version" : "12.17.0"
}
},
{
"identity" : "googledatatransport",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleDataTransport.git",
"state" : {
"revision" : "617af071af9aa1d6a091d59a202910ac482128f9",
"version" : "10.1.0"
}
},
{
"identity" : "googleutilities",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleUtilities.git",
"state" : {
"revision" : "9f183ae842be978784f2963a343682e0c46d8fb3",
"version" : "8.1.2"
}
},
{
"identity" : "grpc-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/grpc-binary.git",
"state" : {
"revision" : "75b31c842f664a0f46a2e590a570e370249fd8f6",
"version" : "1.69.1"
}
},
{
"identity" : "gtm-session-fetcher",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/gtm-session-fetcher.git",
"state" : {
"revision" : "c0ac7575d70050c2973ba2318bd5af47f8e8153a",
"version" : "5.3.0"
}
},
{
"identity" : "interop-ios-for-google-sdks",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/interop-ios-for-google-sdks.git",
"state" : {
"revision" : "040d087ac2267d2ddd4cca36c757d1c6a05fdbfe",
"version" : "101.0.0"
}
},
{
"identity" : "leveldb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/leveldb.git",
"state" : {
"revision" : "a0bc79961d7be727d258d33d5a6b2f1023270ba1",
"version" : "1.22.5"
}
},
{
"identity" : "nanopb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/nanopb.git",
"state" : {
"revision" : "3851d94a41890dea16dc3db34caf60e585cb4163",
"version" : "2.30910.1"
}
},
{
"identity" : "promises",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/promises.git",
"state" : {
"revision" : "f4a19a3c313dc2616c70bb49d29a799fb16be837",
"version" : "2.4.1"
}
}
],
"version" : 3
}
```
### If using CocoaPods, the project's Podfile.lock
N/A (Swift Package Manager)
Contributor guide
Research direction
Start with the linked minimal repro, then inspect Package.swift and Sources/AnalyticsUI/TrackedScreenModifier.swift in Xcode. Reproduce the failure with FirebaseAnalytics 12.15.0–12.17.0, compare it with 12.14.0, and verify the dynamic-library workaround. Done means the static package target's SwiftUI Preview renders successfully without the missing _APM symbols.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ios, swift
- Domain
- build-system, developer-experience, mobile
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100