Skip to content

fix(ios): resolve Swift header with __has_include - #86

Open
lmccombes wants to merge 1 commit into
Expensify:mainfrom
lmccombes:fix/swift-header-has-include
Open

fix(ios): resolve Swift header with __has_include#86
lmccombes wants to merge 1 commit into
Expensify:mainfrom
lmccombes:fix/swift-header-has-include

Conversation

@lmccombes

@lmccombes lmccombes commented Aug 26, 2026

Copy link
Copy Markdown

Details

When USE_FRAMEWORKS is set, the app assumes that the Swift headers will be located at react_native_wallet/react_native_wallet-Swift.h

In my application, when using Expo v57 and setting useFrameworks: "static" in expo-build-properties, Expo disables USE_FRAMEWORKS for this pod

[Expo] Disabling USE_FRAMEWORKS for 94 pods (...react-native-wallet)

This isn't reflected in the RNWallet_USE_FRAMEWORKS flag, and so the build fails, as it is looking in the wrong place for the header file:

node_modules/@expensify/react-native-wallet/ios/RNWallet.mm:5:9: fatal error:
  'react_native_wallet/react_native_wallet-Swift.h' file not found
** BUILD FAILED **

Instead of trying to work out if USE_FRAMEWORKS was set for this pod, we can just use __has_include to check if the header is in the expected location, defaulting back to the non-framework location. This is e.g how Expo themselves handle this situation:

https://github.com/expo/expo/blob/d33a420e1b9046486240fc46d2392e5797318917/packages/expo/ios/Swift.h#L9

Manual Tests

I've confirmed that the library builds successfully with this change against my application.

RNWallet.mm selected its generated Swift header path from
RNWallet_USE_FRAMEWORKS, which the podspec defines whenever
ENV['USE_FRAMEWORKS'] is set. That variable reports what the app requested,
not how this pod is built, and podspecs are evaluated during dependency
resolution -- before anything decides per-pod build types. The macro is
therefore a prediction made before the answer exists.

It predicts wrongly under Expo SDK 55+, whose autolinking downgrades every
pod depending on React-Core to a static library in a pre_install hook. This
podspec declares s.dependency "React-Core", so the pod is built as a static
library while the macro still claims a framework, and compilation fails with:

  RNWallet.mm:5:9: fatal error:
    'react_native_wallet/react_native_wallet-Swift.h' file not found

__has_include is evaluated when the file compiles, after the Swift half of
the target has emitted its header, so it reports what is actually on the
search path. It is correct as a framework, as a static library, and under
Expo's downgrade, with no environment sniffing. This matches the prevailing
pattern for mixed Swift/ObjC React Native modules, including
@react-native-firebase/analytics, @datadog/mobile-react-native,
react-native-screens and react-native-keyboard-controller.

Nothing reads the macro once the import is resolved this way, so the
ENV['USE_FRAMEWORKS'] branch and the _add_compiler_flags helper that serves
it are removed as dead code.
@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@lmccombes

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

exfy-clabot Bot added a commit to Expensify/CLA that referenced this pull request Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant