@@ -43,23 +43,46 @@ def is_new_hermes_runtime(rn_version)
4343
4444require 'digest'
4545require 'fileutils'
46+ require 'open-uri'
4647
4748# SHA256 checksums of `<product>.xcframework.zip` assets published in
4849# sentry-cocoa GitHub releases (same value as the SPM binary target checksum
4950# in sentry-cocoa's `Package.swift`). Register the checksum for each
5051# sentry-cocoa version we ship a prebuilt xcframework for.
52+ #
53+ # Kept in sync with `sentry_cocoa_version` in `RNSentry.podspec` by
54+ # `scripts/update-cocoa.sh set-version <new>`, which downloads the new
55+ # release archive, computes its SHA256, and rewrites the entry below.
5156SENTRY_COCOA_XCFRAMEWORK_CHECKSUMS = {
57+ # `Sentry.xcframework.zip` — the static product. Its enclosing xcframework
58+ # name matches the framework name inside (both `Sentry`), which CocoaPods
59+ # requires to generate `-framework Sentry` correctly and to resolve the
60+ # `Sentry` module. `Sentry-Dynamic.xcframework` would ship the same
61+ # `Sentry.framework` inside but under a mismatched enclosing name, so
62+ # CocoaPods generates `-framework Sentry-Dynamic` and fails at link.
5263 '9.19.1' => {
53- # `Sentry.xcframework.zip` — the static product. Its enclosing xcframework
54- # name matches the framework name inside (both `Sentry`), which CocoaPods
55- # requires to generate `-framework Sentry` correctly and to resolve the
56- # `Sentry` module. `Sentry-Dynamic.xcframework` would ship the same
57- # `Sentry.framework` inside but under a mismatched enclosing name, so
58- # CocoaPods generates `-framework Sentry-Dynamic` and fails at link.
5964 'Sentry' => 'd6d545af17e49851cda2747b0f45cde78ce08ea37709dde5a956c6b4671224e8' ,
6065 } ,
6166} . freeze
6267
68+ # Static map from xcframework slice directory name to the Xcode SDK selector
69+ # it should be attached to. `sentry-cocoa`'s `Sentry.xcframework` layout is
70+ # stable across releases — same slice names come out of every build — so we
71+ # hardcode the mapping rather than scanning the extracted bundle. Add a
72+ # new entry here if `sentry-cocoa` ever ships a new platform slice.
73+ SENTRY_XCFRAMEWORK_SLICES_BY_SDK = {
74+ 'iphoneos' => %w[ ios-arm64_arm64e ] ,
75+ 'iphonesimulator' => %w[ ios-arm64_x86_64-simulator ] ,
76+ 'maccatalyst' => %w[ ios-arm64_arm64e_x86_64-maccatalyst ] ,
77+ 'macosx' => %w[ macos-arm64_arm64e_x86_64 ] ,
78+ 'appletvos' => %w[ tvos-arm64_arm64e ] ,
79+ 'appletvsimulator' => %w[ tvos-arm64_x86_64-simulator ] ,
80+ 'watchos' => %w[ watchos-arm64_arm64_32_arm64e_armv7k ] ,
81+ 'watchsimulator' => %w[ watchos-arm64_x86_64-simulator ] ,
82+ 'xros' => %w[ xros-arm64_arm64e ] ,
83+ 'xrsimulator' => %w[ xros-arm64_x86_64-simulator ] ,
84+ } . freeze
85+
6386# Ensures `<sdk_root>/ios/Vendor/<product>.xcframework` exists.
6487#
6588# On first invocation, downloads the prebuilt xcframework zip from
@@ -96,8 +119,13 @@ def ensure_sentry_xcframework(version, product = 'Sentry')
96119 "#{ version } /#{ product } .xcframework.zip"
97120
98121 Pod ::UI . puts "[Sentry] Downloading #{ product } #{ version } from GitHub Releases…" if defined? ( Pod ::UI )
99- unless system ( 'curl' , '-sSfL' , '-o' , zip_path , url )
100- raise "Failed to download #{ url } "
122+ begin
123+ URI . open ( url , redirect : true ) do |remote |
124+ File . open ( zip_path , 'wb' ) { |f | IO . copy_stream ( remote , f ) }
125+ end
126+ rescue OpenURI ::HTTPError , SocketError , StandardError => e
127+ FileUtils . rm_f ( zip_path )
128+ raise "Failed to download #{ url } : #{ e . class } : #{ e . message } "
101129 end
102130
103131 actual_checksum = Digest ::SHA256 . file ( zip_path ) . hexdigest
@@ -125,50 +153,3 @@ def ensure_sentry_xcframework(version, product = 'Sentry')
125153 target_dir
126154end
127155
128- # Returns a hash of `<xcconfig SDK name> => [slice_id, ...]` for the slice
129- # directories inside an xcframework bundle.
130- #
131- # Xcode's `-F <dir>` does not descend into an `.xcframework` bundle at
132- # search-path lookup time — it only sees `Sentry.xcframework` as a directory
133- # and doesn't find `Sentry.framework` inside. Callers use these groupings
134- # to emit SDK-conditional `FRAMEWORK_SEARCH_PATHS[sdk=…*]` xcconfig entries
135- # so each SDK build only sees its own slice — putting all slices under a
136- # single unconditional search path lets Xcode's Swift module precompiler
137- # stumble into an incompatible slice and fail with
138- # "unsupported Swift architecture".
139- #
140- # Slice-name convention is stable across the xcframeworks Apple has ever
141- # published:
142- # ios-*-simulator -> iphonesimulator
143- # ios-*-maccatalyst -> maccatalyst
144- # ios-… -> iphoneos
145- # tvos-*-simulator -> appletvsimulator
146- # tvos-… -> appletvos
147- # watchos-*-simulator -> watchsimulator
148- # watchos-… -> watchos
149- # xros-*-simulator -> xrsimulator
150- # xros-… -> xros
151- # macos-… -> macosx
152- def sentry_xcframework_slices_by_sdk ( xcframework_dir )
153- slice_ids = Dir . children ( xcframework_dir ) . select do |name |
154- File . directory? ( File . join ( xcframework_dir , name ) ) && name != '_CodeSignature'
155- end . sort
156-
157- slice_ids . each_with_object ( { } ) do |slice , groups |
158- sdk = _sentry_sdk_for_slice ( slice )
159- next unless sdk # unknown platform prefix — skip rather than mis-attach
160- ( groups [ sdk ] ||= [ ] ) << slice
161- end
162- end
163-
164- def _sentry_sdk_for_slice ( slice_id )
165- return 'maccatalyst' if slice_id . include? ( '-maccatalyst' )
166- simulator = slice_id . end_with? ( '-simulator' )
167- case
168- when slice_id . start_with? ( 'ios-' ) then simulator ? 'iphonesimulator' : 'iphoneos'
169- when slice_id . start_with? ( 'tvos-' ) then simulator ? 'appletvsimulator' : 'appletvos'
170- when slice_id . start_with? ( 'watchos-' ) then simulator ? 'watchsimulator' : 'watchos'
171- when slice_id . start_with? ( 'xros-' ) then simulator ? 'xrsimulator' : 'xros'
172- when slice_id . start_with? ( 'macos-' ) then 'macosx'
173- end
174- end
0 commit comments