Skip to content

Commit a116630

Browse files
fix: explicitly declare Photos framework on packages that import PHAsset/PHAssetResource
1 parent 73be237 commit a116630

4 files changed

Lines changed: 36 additions & 4 deletions

File tree

okf-bundle/ios-spm-native-imports.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ for f in $(grep -rl "@import Firebase" packages/*/ios 2>/dev/null); do
203203
done
204204
```
205205

206-
A clean run should print nothing once `RNFBAuthModule.mm` above is fixed.
206+
A clean run should print nothing.
207207

208208
**Check 2 — pure-Swift-core SPM products imported directly from a `.mm` file** (the deeper failure mode above — no `#elif` wording fixes this, only the helper-class delegation does):
209209

@@ -213,7 +213,22 @@ for f in $(grep -rl "FirebaseStorage\|FirebaseRemoteConfig\|FirebaseDatabase\|Fi
213213
done
214214
```
215215

216-
A clean run should print nothing; every `.mm` file for these five packages (the four above, plus Auth per [above](#firebaseauths-hidden-pure-swift-core)) should only import its package's `*Helper.h` (plus `RNFBDatabaseQueue.h`/`RNFBDatabaseConstants.h` for database), never Firebase headers. Auth is not yet fixed, so this check will currently flag `RNFBAuthModule.mm`.
216+
A clean run should print nothing; every `.mm` file for these five packages (the four above, plus Auth per [above](#firebaseauths-hidden-pure-swift-core)) should only import its package's `*Helper.h` (plus `RNFBDatabaseQueue.h`/`RNFBDatabaseConstants.h` for database), never Firebase headers.
217+
218+
## Unrelated linker bug found along the way — missing `Photos.framework` declaration
219+
220+
**Not part of the SPM dual-import bug class above** — recorded here because it was found while validating the Auth fix and blocked the same `yarn tests:ios:build` command. Once every native-import fix above was in place, the debug SPM build progressed past compilation into linking and failed with:
221+
222+
```
223+
Undefined symbols for architecture arm64:
224+
"_OBJC_CLASS_$_PHAsset", referenced from:
225+
in RNFBUtilsModule.o
226+
ld: symbol(s) not found for architecture arm64
227+
```
228+
229+
**Root cause:** `packages/app/ios/RNFBApp/RNFBUtilsModule.{h,mm}` and `packages/storage/ios/RNFBStorage/RNFBStorageCommon.{h,m}` both `#import <Photos/Photos.h>` and use `PHAsset`/`PHAssetResource`, but neither `RNFBApp.podspec` nor `RNFBStorage.podspec` ever declared `s.frameworks = 'Photos'` (confirmed absent on `main` too — this is not an SPM regression). That was never a problem for CocoaPods-only static-library builds, where the final app-level link resolves all pods' symbols together in one pass. But this repo's `Podfile` uses `use_frameworks!` with dynamic linkage, so each pod compiles to its own standalone dynamic framework (`clang++ -dynamiclib ...`) that must resolve **all** of its own undefined symbols at its own link step -- it can't defer to the app target. CocoaPods populates each pod's `OTHER_LDFLAGS` (`-framework X` per framework) directly from the podspec's declared `s.frameworks`/dependency graph, not from scanning source for `#import`/Clang-module autolink info, so an undeclared system framework silently has no `-framework` flag no matter how the header is imported.
230+
231+
**Fix:** declared `s.ios.frameworks = 'Photos'` / `s.osx.frameworks = 'Photos'` (iOS + macOS only -- PhotoKit doesn't exist on tvOS, even though these files currently have no tvOS guard either; that's a pre-existing, separate gap left untouched here) in both podspecs, matching the existing `s.frameworks = 'AdSupport'` convention already used in `RNFBAnalytics.podspec`. Verified the regenerated `RNFBApp.debug.xcconfig`/`RNFBStorage.debug.xcconfig` `OTHER_LDFLAGS` now include `-framework "Photos"`, and `yarn tests:ios:build` succeeds end-to-end.
217232

218233
## Related
219234

packages/app/RNFBApp.podspec

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ Pod::Spec.new do |s|
3838
"DEFINES_MODULE" => "YES",
3939
}
4040

41+
# RNFBUtilsModule.mm uses PHAsset (Photos.framework) to resolve local asset paths.
42+
# Not declaring this explicitly used to work by luck (CocoaPods normally relies on
43+
# this declaration -- not Clang autolinking -- to populate OTHER_LDFLAGS), but with
44+
# use_frameworks! each pod is a standalone dynamic framework that must resolve its
45+
# own symbols at its own link step, so the missing declaration now surfaces as
46+
# "Undefined symbols ... _OBJC_CLASS_$_PHAsset". iOS/macOS only -- PhotoKit doesn't
47+
# exist on tvOS.
48+
s.ios.frameworks = 'Photos'
49+
s.osx.frameworks = 'Photos'
50+
4151
# React Native dependencies
4252
if defined?(install_modules_dependencies()) != nil
4353
install_modules_dependencies(s);

packages/storage/RNFBStorage.podspec

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ Pod::Spec.new do |s|
5151
'HEADER_SEARCH_PATHS' => '"$(PODS_TARGET_SRCROOT)/ios/generated/RNFBStorageTurboModules" "$(PODS_TARGET_SRCROOT)/ios/generated"'
5252
}
5353

54+
# RNFBStorageCommon.m uses PHAsset/PHAssetResource (Photos.framework) for local
55+
# asset uploads. See RNFBApp.podspec for why this must be declared explicitly
56+
# rather than relying on Clang autolinking. iOS/macOS only -- PhotoKit doesn't
57+
# exist on tvOS.
58+
s.ios.frameworks = 'Photos'
59+
s.osx.frameworks = 'Photos'
60+
5461
if defined?($RNFirebaseAsStaticFramework)
5562
Pod::UI.puts "#{s.name}: Using overridden static_framework value of '#{$RNFirebaseAsStaticFramework}'"
5663
s.static_framework = $RNFirebaseAsStaticFramework

tests/ios/Podfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2314,7 +2314,7 @@ SPEC CHECKSUMS:
23142314
RNCAsyncStorage: 481acf401089f312189e100815088ea5dafc583c
23152315
RNDeviceInfo: d79872e11c8e9c4de0d65b0ee6e0cee719f37fea
23162316
RNFBAnalytics: 3b213b559edf8f62270af58c799b517f9abd1d6a
2317-
RNFBApp: 79f96d33adc789e867ecfd561c57304e0e8cf86d
2317+
RNFBApp: dd448276ce0a9ef8f3bcb1a66cc588cd24197da0
23182318
RNFBAppCheck: c943ba51cac50bfdbe1aa5fab3b1b97c4ac8200e
23192319
RNFBAppDistribution: f155c1bd3fa4d2ecd4930757101e854f8cdc0c50
23202320
RNFBAuth: 74683b7280b7ce1cf2365cb836e8f63fdef3a192
@@ -2328,7 +2328,7 @@ SPEC CHECKSUMS:
23282328
RNFBML: 01095dc4aca9b6bd3806242db465059f8c3273a4
23292329
RNFBPerf: a622416435e2a81408edb6d7352cc44cdc1cca23
23302330
RNFBRemoteConfig: ab933ea83779fbb4b9de2f9789f8587e85ce8a76
2331-
RNFBStorage: 266e86ae539ece1b69387dd1dcf743e822682ae2
2331+
RNFBStorage: 90ae11c722b8c29d1d9ddf6ca26aaea61f287c2c
23322332
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
23332333
Yoga: 66a9fd80007d5d5fce19d1676ce17b4d5e16e9b1
23342334

0 commit comments

Comments
 (0)