feat(ios): Consume sentry-cocoa as a prebuilt xcframework by default#6413
Conversation
Semver Impact of This PR⚪ None (no version bump detected) 📋 Changelog PreviewThis is how your changes will appear in the changelog.
🤖 This preview updates automatically when you update the PR. |
|
pod install now downloads Sentry.xcframework.zip from sentry-cocoa's GitHub release (SHA256-verified) and caches it under ~/Library/Caches/sentry-react-native/xcframeworks/<version>/, instead of building Sentry from source as a CocoaPod. Sentry symbols are then statically linked into the app binary (no framework embed, no dylib dep) via `FRAMEWORK_SEARCH_PATHS[sdk=…*]` + clang's -fmodules-autolink. Motivation: - CocoaPods trunk is winding down; we needed a path off it that also sidesteps the Xcode 16/26 archive bug that hits any signed SPM binary xcframework (`Signatures/*.signature` collision). - Consuming via CocoaPods' `vendored_frameworks` pipeline goes through a different code path and is unaffected. Fallback: set `SENTRY_USE_XCFRAMEWORK=0` before pod install to restore the source-built `Sentry` CocoaPod (for offline builds behind a restrictive proxy, or projects with another pod that transitively depends on the Sentry CocoaPod). Cache location is user-writable (not inside node_modules), which means pnpm's isolated store and Yarn PnP work without changes. Override the cache root with `SENTRY_XCFRAMEWORK_CACHE_DIR`. Verified end-to-end against alpha.3 on: - Real device signed archive (Apple accepts, codesign strict-verify passes) - Native crash → dSYM upload → Sentry frames symbolicated - RN 0.71 archive (via SKIP_BUNDLING) with 21k Sentry symbols in dSYM - EAS Build with npm, pnpm-isolated, and `SENTRY_USE_XCFRAMEWORK=0` - Second EAS build after version bump (no stale-cache pollution) Reapplies the content of PR #6381 (merged prematurely as part of the alpha.3 release, then rolled back via #6412) with the pnpm cache-location fix baked in from the start this time. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
6109f6d to
04444cd
Compare
|
I've spent quite a lot of time checking different scenarios with embedded xcframework to make sure everything works, and want to share the results here. So here is what I've tried:
In addition to that, default vendored static xcframework (number 4 in the list) and fallback source-built CocoaPod (num. 6) produce statically linked binary with the identical shape, and there is no code path in this PR that would've included a dynamic Sentry framework. |
iOS (legacy) Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| d0e3b3e+dirty | 3854.77 ms | 1218.58 ms | -2636.19 ms |
| 5125c43+dirty | 3846.45 ms | 1221.12 ms | -2625.32 ms |
| 580fb5c+dirty | 3836.13 ms | 1218.72 ms | -2617.41 ms |
| 7887847+dirty | 3849.83 ms | 1227.35 ms | -2622.48 ms |
| a216cb9+dirty | 3839.33 ms | 1225.26 ms | -2614.07 ms |
| 40c9884+dirty | 3837.72 ms | 1226.61 ms | -2611.11 ms |
| a5d243c+dirty | 3842.35 ms | 1214.29 ms | -2628.06 ms |
| f170ec3+dirty | 3822.26 ms | 1218.33 ms | -2603.93 ms |
| 68672fc+dirty | 3841.58 ms | 1228.89 ms | -2612.69 ms |
| ae37560+dirty | 3832.10 ms | 1219.09 ms | -2613.02 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| d0e3b3e+dirty | 4.98 MiB | 6.51 MiB | 1.53 MiB |
| 5125c43+dirty | 5.15 MiB | 6.68 MiB | 1.53 MiB |
| 580fb5c+dirty | 4.98 MiB | 6.46 MiB | 1.48 MiB |
| 7887847+dirty | 4.98 MiB | 6.46 MiB | 1.48 MiB |
| a216cb9+dirty | 4.98 MiB | 6.51 MiB | 1.53 MiB |
| 40c9884+dirty | 4.98 MiB | 6.51 MiB | 1.53 MiB |
| a5d243c+dirty | 5.15 MiB | 6.68 MiB | 1.53 MiB |
| f170ec3+dirty | 5.15 MiB | 6.69 MiB | 1.53 MiB |
| 68672fc+dirty | 5.15 MiB | 6.71 MiB | 1.55 MiB |
| ae37560+dirty | 5.15 MiB | 6.70 MiB | 1.54 MiB |
📲 Install BuildsAndroid
|
Android (legacy) Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| eb93136+dirty | 416.18 ms | 467.32 ms | 51.14 ms |
| ae37560+dirty | 470.40 ms | 564.12 ms | 93.72 ms |
| 5b7e8a7+dirty | 418.55 ms | 488.46 ms | 69.91 ms |
| c823bb5+dirty | 409.87 ms | 478.57 ms | 68.70 ms |
| 3817909+dirty | 406.67 ms | 416.58 ms | 9.91 ms |
| bc0d8cf+dirty | 412.37 ms | 466.26 ms | 53.89 ms |
| 5a23c47+dirty | 423.85 ms | 466.47 ms | 42.62 ms |
| 0a147b2+dirty | 464.71 ms | 538.81 ms | 74.09 ms |
| a50b33d+dirty | 500.81 ms | 532.11 ms | 31.30 ms |
| 7887847+dirty | 416.61 ms | 462.04 ms | 45.43 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| eb93136+dirty | 48.30 MiB | 53.58 MiB | 5.28 MiB |
| ae37560+dirty | 48.30 MiB | 53.60 MiB | 5.29 MiB |
| 5b7e8a7+dirty | 48.30 MiB | 53.58 MiB | 5.28 MiB |
| c823bb5+dirty | 48.30 MiB | 53.58 MiB | 5.28 MiB |
| 3817909+dirty | 43.75 MiB | 48.08 MiB | 4.33 MiB |
| bc0d8cf+dirty | 48.30 MiB | 53.48 MiB | 5.18 MiB |
| 5a23c47+dirty | 49.74 MiB | 54.82 MiB | 5.07 MiB |
| 0a147b2+dirty | 49.74 MiB | 55.08 MiB | 5.34 MiB |
| a50b33d+dirty | 43.75 MiB | 48.08 MiB | 4.33 MiB |
| 7887847+dirty | 49.74 MiB | 54.81 MiB | 5.07 MiB |
iOS (new) Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 580fb5c+dirty | 3835.45 ms | 1218.61 ms | -2616.84 ms |
| d0e3b3e+dirty | 3846.64 ms | 1226.27 ms | -2620.38 ms |
| a216cb9+dirty | 3853.25 ms | 1224.77 ms | -2628.48 ms |
| 37a2091+dirty | 3865.27 ms | 1223.92 ms | -2641.35 ms |
| 40c9884+dirty | 3826.11 ms | 1217.04 ms | -2609.07 ms |
| 4e0ba9c+dirty | 3856.39 ms | 1234.44 ms | -2621.95 ms |
| 0b5a379+dirty | 3857.69 ms | 1230.34 ms | -2627.35 ms |
| 68672fc+dirty | 3832.22 ms | 1228.29 ms | -2603.93 ms |
| 2c735cc+dirty | 1223.33 ms | 1224.38 ms | 1.04 ms |
| 6acdf1d+dirty | 3835.35 ms | 1218.30 ms | -2617.06 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 580fb5c+dirty | 4.98 MiB | 6.46 MiB | 1.48 MiB |
| d0e3b3e+dirty | 4.98 MiB | 6.51 MiB | 1.53 MiB |
| a216cb9+dirty | 4.98 MiB | 6.51 MiB | 1.53 MiB |
| 37a2091+dirty | 5.15 MiB | 6.70 MiB | 1.54 MiB |
| 40c9884+dirty | 4.98 MiB | 6.51 MiB | 1.53 MiB |
| 4e0ba9c+dirty | 5.15 MiB | 6.67 MiB | 1.51 MiB |
| 0b5a379+dirty | 5.15 MiB | 6.70 MiB | 1.54 MiB |
| 68672fc+dirty | 5.15 MiB | 6.71 MiB | 1.55 MiB |
| 2c735cc+dirty | 3.38 MiB | 4.74 MiB | 1.35 MiB |
| 6acdf1d+dirty | 4.98 MiB | 6.51 MiB | 1.53 MiB |
Android (new) Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 1122a96+dirty | 510.16 ms | 542.00 ms | 31.84 ms |
| 7ac3378+dirty | 410.67 ms | 442.60 ms | 31.92 ms |
| b04af96+dirty | 430.33 ms | 485.98 ms | 55.65 ms |
| 3817909+dirty | 357.52 ms | 391.52 ms | 34.00 ms |
| 20fbd51+dirty | 594.38 ms | 655.35 ms | 60.97 ms |
| 0a147b2+dirty | 442.80 ms | 522.24 ms | 79.44 ms |
| a5d243c+dirty | 499.20 ms | 525.62 ms | 26.42 ms |
| 2363c0f+dirty | 419.48 ms | 463.92 ms | 44.44 ms |
| 5257d80+dirty | 472.37 ms | 494.54 ms | 22.17 ms |
| 0a9e622+dirty | 425.22 ms | 457.00 ms | 31.78 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 1122a96+dirty | 48.30 MiB | 53.54 MiB | 5.24 MiB |
| 7ac3378+dirty | 43.94 MiB | 48.99 MiB | 5.05 MiB |
| b04af96+dirty | 49.74 MiB | 55.00 MiB | 5.26 MiB |
| 3817909+dirty | 43.94 MiB | 48.94 MiB | 5.00 MiB |
| 20fbd51+dirty | 49.74 MiB | 54.81 MiB | 5.07 MiB |
| 0a147b2+dirty | 49.74 MiB | 55.08 MiB | 5.34 MiB |
| a5d243c+dirty | 48.30 MiB | 53.54 MiB | 5.23 MiB |
| 2363c0f+dirty | 49.74 MiB | 54.84 MiB | 5.10 MiB |
| 5257d80+dirty | 48.30 MiB | 53.58 MiB | 5.28 MiB |
| 0a9e622+dirty | 49.74 MiB | 55.09 MiB | 5.34 MiB |
📢 Type of change
📜 Description
Retry of #6381, which was merged into the
release/8.18.0-alpha.3cut prematurely and then rolled back via #6412. Content re-applied, this time with the pnpm-isolated cache-location fix baked in from the start and validated end-to-end via8.18.0-alpha.3on a real bare RN app + EAS Build.pod installnow downloadsSentry.xcframework.zipfrom sentry-cocoa's GitHub release (SHA256-verified) and caches it under~/Library/Caches/sentry-react-native/xcframeworks/<version>/, instead of building Sentry from source as a CocoaPod. Sentry symbols are then statically linked into the app binary (no framework embed, no dylib dep) viaFRAMEWORK_SEARCH_PATHS[sdk=…*]+ clang's-fmodules-autolink.Override with:
SENTRY_USE_XCFRAMEWORK=0— fall back to the source-builtSentryCocoaPod (for offline builds, restrictive proxies, or projects with another pod that transitively depends on theSentryCocoaPod).SENTRY_XCFRAMEWORK_CACHE_DIR— override cache root (defaults to~/Library/Caches/sentry-react-native/xcframeworks).💡 Motivation and Context
Signatures/*.signaturecollision).vendored_frameworkspipeline goes through a different code path and is unaffected by that bug.node_modules) so pnpm's isolated store and Yarn PnP work without changes.📝 Checklist
🔮 Next steps