Repository navigation
fix: support Swift builds that use an Objective-C bridging header - #4364
Merged
Saad Najmi (Saadnajmi) merged 4 commits intoOct 14, 2026
Conversation
Hosts can compile FURN's Swift sources against React Native through an Objective-C bridging header instead of a `React` clang module. - Import `React` in the Avatar and NativeDatePicker iOS Swift sources only when the module is available. - Implement the macOS Paper Callout `focusWindow` and `blurWindow` commands in Swift and declare them with `RCT_EXTERN_METHOD`, so FRNCalloutManager.m no longer imports the generated FRNNativeCore-Swift.h. With a bridging header, that generated header also declares the internal RCTCalloutManager class, which duplicates the `RCT_EXTERN_MODULE` interface. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: ea215348-486c-45ef-8205-2a81a1dd75a7
Contributor
Bundle size reportTree-shaken, minified production esbuild bundles with React and React Native runtimes externalized.
The job is advisory: size changes are reported but do not fail the pull request. Bundle or analysis errors still fail. |
…rces FRNAppearanceAdditions.m and FRNDatePickerManager.m included RCTUIManager.h and RCTBridgeModule.h by bare name, which only resolves in hosts that also expose React Native headers without the React/ prefix. Use the canonical <React/...> form, which the rest of these files and CocoaPods already use. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: ea215348-486c-45ef-8205-2a81a1dd75a7
…ocusZone The macOS FocusZone implementation included "RCTi18nUtil.h" by bare name and with different capitalization from React Native's React/Modules/RCTI18nUtil.h, so it only resolved through a case-insensitive bare-name header map. Use the canonical <React/RCTI18nUtil.h> form. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: ea215348-486c-45ef-8205-2a81a1dd75a7
Saad Najmi (Saadnajmi)
marked this pull request as ready for review
October 13, 2026 22:47
…cusZone Mark the unused `index` and `stop` parameters of the indexOfObjectPassingTest: block in RCTFocusZone.m as `__unused` so the file compiles cleanly when -Wunused-parameter is treated as an error. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d7aea072-fc8e-4a8d-890a-81311025130d
1 of 10 tasks
Tommy Nguyen (tido64)
approved these changes
Oct 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Platforms Impacted
Description of changes
Office builds FURN's native Swift with its own build system and is moving React Native macOS 0.81 to its Swift Package Manager layout, which no longer exports a
Reactclang module. There, FURN's Swift targets see React Native's headers through an Objective-C bridging header: each target's existing manager header, which already imports<React/...>. Office is also dropping its export of React Native headers by bare name. These changes let the same sources build both upstream (CocoaPods,Reactmodule) and in Office:packages/experimental/Avatar/ios/AvatarViewManager.swift,packages/experimental/NativeDatePicker/ios/DatePickerManager.swift, andDatePickerDelegate.swift: wrapimport Reactin#if canImport(React). The macOS Swift sources already guard it with#if USE_REACT_AS_MODULE, which upstream iOS CocoaPods builds don't define.canImport(React)keeps upstream behavior unchanged.packages/agentic/native-core/macos/components/Callout/paper/: with a bridging header, the generatedFRNNativeCore-Swift.halso declares internal Swift classes, including@interface RCTCalloutManager : RCTViewManager.FRNCalloutManager.mimported that header only so itsfocusWindow/blurWindowbodies could callFRNCalloutView. Against itsRCT_EXTERN_MODULE(RCTCalloutManager, RCTViewManager), it fails withduplicate interface definition for class 'RCTCalloutManager'.CalloutManager.swift: implementfocusWindow/blurWindow, still dispatching the view lookup to the main queue. Thenonisolated(unsafe)local keeps the closure clean under stricter Swift concurrency checking.FRNCalloutManager.m: declare both withRCT_EXTERN_METHODand drop the Swift header import. JS command names, selectors, and arguments are unchanged.RCTCalloutComponentView.mm(Fabric) still imports the generated header.packages/experimental/AppearanceAdditions/ios/FRNAppearanceAdditions.m,packages/experimental/NativeDatePicker/ios/FRNDatePickerManager.m, andpackages/agentic/native-core/macos/components/FocusZone/shared/RCTFocusZone.m: importRCTUIManager.h,RCTBridgeModule.h, andRCTI18nUtil.has<React/...>rather than by bare name. They were the only FURN sources still including React Native headers by bare name. FocusZone's"RCTi18nUtil.h"also differed in case from React Native'sRCTI18nUtil.h, so it only resolved through a case-insensitive header map. The<React/...>form is canonical, is already used by the rest of these files, and works with CocoaPods.packages/agentic/native-core/macos/components/FocusZone/shared/RCTFocusZone.m: also mark the unusedindexandstopparameters of theindexOfObjectPassingTest:block innextViewToFocusInHierarchyForAction:as__unused. Office's macOS build treats-Wunused-parameteras an error and carries this change as a local patch. No behavior change. Folded in from fix(native-core): silence unused block parameter warnings in macOS FocusZone #4365.tests/native-ownership.test.mjs: only the Fabric adapter imports the generated header. Paper commands are declared withRCT_EXTERN_METHODand implemented in Swift.README.md: document that rule for future Paper managers.native-core,experimental-avatar,experimental-native-date-picker, andexperimental-appearance-additions.Independent of #4363 (the
FRNCalloutalias). The two merge cleanly in either order, to the same tree. With both applied, the alias'sRCT_EXTERN_MODULE(FRNCalloutManager, RCTCalloutManager)also avoids a second duplicate interface in bridging-header builds.Verification
swiftc -import-objc-headerwithFRNCalloutManager.h, thenclang -fsyntax-only FRNCalloutManager.m):main: fails withduplicate interface definition for class 'RCTCalloutManager'.RegionBasedIsolation,InferSendableFromCaptures, andGlobalConcurrencyupcoming features plus-warnings-as-errors. Under-strict-concurrency=complete, the new methods add no diagnostics; capturingselfdirectly would warn at both call sites.clang -fsyntax-onlyagainst React Native headers exposed only as<React/...>:mainfails with'RCTUIManager.h' file not foundand'RCTBridgeModule.h' file not found. This branch compiles both files.-Werror=nonportable-include-path):mainfails with'RCTi18nUtil.h' file not found. This branch compiles. Spelling it<React/RCTi18nUtil.h>fails the case check.<React/...>includes match the on-disk case.indexOfObjectPassingTest:block fromRCTFocusZone.min a stub function withxcrun clang -fsyntax-only -fobjc-arc -Wall -Wextra -Wunused-parameter -Werror(Xcode 26.4.1).mainfails withunused parameter 'index'andunused parameter 'stop'. This branch passes. The same change and changeset passedCheck for Changesetsin fix(native-core): silence unused block parameter warnings in macOS FocusZone #4365.yarn workspace @fluentui-react-native/native-core lint: passed.yarn workspace @fluentui-react-native/native-core test(build, stories typecheck, node tests, Jest): passed. Ownership tests: 6/6, and 7/7 when merged with fix(native-core): restore macOS Paper FRNCallout manager alias #4363.yarn oxfmt --checkon the changed README and test: passed.yarn change:check: passed.swiftc -parseon the three iOS Swift files: passed..yarn/releases/yarn-4.18.0.cjs.iOS PR,macOS PR, andmacOS Storybook PRnative builds.focusWindow/blurWindow.FRNCalloutManager.mhitsduplicate interface definition for class 'RCTCalloutManager', and iOSimport Reactrequires aReactmoduleReactmoduleFRNAppearanceAdditions.m,FRNDatePickerManager.m, andRCTFocusZone.mneed hosts to export React Native headers by bare name, case-insensitively forRCTi18nUtil.h<React/...>, with the exact header caseRCTFocusZone.mfails to compile when-Wunused-parameteris an error (unusedindexandstopblock parameters)__unused, so it compiles cleanlyPull request checklist
This PR has considered (when applicable):