Closed lodev09 closed 1 month ago
Hi @lodev09, thanks for maintaining a library for React Native and thank you for the issue.
As the name implies, the Bridgless mode means No Bridge. So it makes sense that the bridge
instance is actually nil
: no bridge is actually initialized.
There are two questions that I need to ask you:
My guess is that nobody is setting the bridge in the ViewManager
, after it is created: in bridgeless mode, that's kind of expected, given that there is no bridge. But in theory it should work thanks to the Interop Layer.
I'll have a look at it later today or tomorrow.
As the name implies, the Bridgless mode means No Bridge. So it makes sense that the bridge instance is actually nil: no bridge is actually initialized.
Hmmm, interesting. I'm wondering how the RN Modal works on bridgeless then? It uses exactly the same code to set the TouchHandler -- the only difference is that my library is written in swift.
- Are you migrating the component to Fabric?
- Are you trying to use the component throught the Interop Layer?
I'm trying to run it through Interop layer first and then ultimately fabric. As I mentioned, everything works fine aside from the bridge being nil
.
I just need the TouchHandler to work on New Arch :/
I'm wondering how the RN Modal works on bridgeless then?
RN Modals are actually already migrated to Fabric. When you run the new architecture, the component that is loaded is this one.
Ok, I got the issue. I'll work on a fix as there could be other libraries that rely on the bridge property to be set and it is currently not set in the interop layer.
I hope I'll be able to send the fix out before EOW.
Okay.. thank you so much @cipolleschi š
Quick question: If I understand correctly, swift is not yet supported for Fabric components right?
swift is not yet supported for Fabric components right?
Tricky question! Technically, no, it is not supported. What we mean with that is that you can't create a Fabric component using only Swift.
However, you can create a thin wrapper in objective-c++ and then forward the various calls to Swift. We haven't experimented with that setup a lot, and we are aware that there are some things that are not compatible and that will require some wrapping to make them work in Swift.
So.. https://github.com/facebook/react-native/pull/45329 should fix the crash. But, from what I am seeing, the buttons are not tappable... :/
Yeah.. I use the bridge to mainly setSize
and create an RCTTouchHandler
instance to be attached to the container view. I'm hoping this is supported on the Interop layer.
I need to ask around and investigate... I'll keep you posted!
That was quick... xD I found that:
RCTTouchHandler
is for the Old ArchRCTSurfaceTouchHandler
is for the New Arch.I made a quick experiment in TrueSheetView.swift
:
// ...
class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
//...
private var touchHandler: RCTTouchHandler
+ private var surfaceTouchHandler: RCTSurfaceTouchHandler
// ..
init(with bridge: RCTBridge) {
// ...
touchHandler = RCTTouchHandler(bridge: bridge)
+ surfaceTouchHandler = RCTSurfaceTouchHandler()
//...
override func insertReactSubview(_ subview: UIView!, at index: Int) {
// ...
containerView = subview
- touchHandler.attach(to: containerView)
+ touchHandler.attach(to: subview)
+ surfaceTouchHandler.attach(to: subview)
}
//..
override func removeReactSubview(_ subview: UIView!) {
//...
touchHandler.detach(from: subview)
+ surfaceTouchHandler.detach(from: subview)
//...
And, of course, adding the following in the bridging header
#import <React/RCTTouchHandler.h>
+ #import <React/RCTSurfaceTouchHandler.h>
#import <React/RCTScrollView.h>
https://github.com/facebook/react-native/assets/11162307/83ddc883-9b49-4f17-9909-9d94588777bc
sizings looks a bit off, though... :(
Wow thank you! :D Just need a new arch condition and should be go to go with the touch handler!
sizings looks a bit off, though... :(
Yeah, looks like bridge.uiManager.setSize
isn't working... is there any alternative? š
Code is here:
https://github.com/lodev09/react-native-true-sheet/blob/643f4e8f39aabfe1403de74042b25bdb392f18ce/ios/TrueSheetView.swift#L147-L152
It turns out, that method was not implemented in the interop layer for Bridgeless. I'll try to work on that tomorrow!
You're awesome @cipolleschi. Thank you so much!
Thank you for reporting the issue and for providing a way for me to work on that!
(Anyway... start thinking about migrating it to Fabric! š It will be needed, at some point! Happy to help there as well)
@cipolleschi yes, I'm really eager to migrate it to fabric -- it's just a bummer that swift isn't supported out of the box. But we'll get there šŖ
This is my first native ios/android project so I'm not 100% familiar with all this yet š
@lodev09 I looked into this issue a little bit more.
The method that is missing is RCTUIManager setSize:forView:
.
The reason why it hasn't been implemented in the Interop Layer is architectural. In the Old Architecture, we have a native layer that creates a tree of views. Every view is backed by a shadow view that is used to compute the layout. The JS React tree talks to the platform and creates the Native tree and the Shadow tree at the same time. The old RCTUIManager has a mapping between native view and shadow view. The native layer is the source of truth.
In the New Architecture, we have a shadow tree implementation in C++. In the New Architecture, the Shadow Tree drives everything and it creates the Native tree. The Native views don't have a handle to get the shadow views anymore and they can't really change the layout from the Native layer. The shadow layer is the source of truth.
Due to this, we cannot really port the setSize
method back to the Interop Layer.
I searched on Github and there are not a lot of libraries that uses that method (< 1% of all the React Native libraries) so it does not really make sense to support this API due to its architectural incompatibility with the New Architecture and its low usage.
My suggestion would be to migrate your library to Fabric properly and support both architectures.
We have some guides on how to do it:
And you can use the New Architecture implementation of the React Native Modal component as base implementation for the Fabric version of it.
I would also love to help with review and suggestions on how to bridge ObjC++ with Swift. I made some experiments with modules in the past, here and here, but I never had the time to try with Componentes.
I hope these pointers can help you move forward with this.
@cipolleschi I see. I'm going to implement an alternative approach to updating the size as a short term solution for now, maybe in the JS side.
I agree with migrating to Fabric for the long term. I might just convert it all to ObjC š
Anyways, thanks again for your help!
@lodev09 I am closing this issue. Since it's been answered above by @cipolleschi. Thank you!
Description
I maintain a native component library and trying to make it work with New Architecture interop. It builds without problem. However, the
bridge
in the view manager instance isnil
and causing the component to crash.To give context, the library is similar to RN Modal where it uses the view component as a host view of a view controller. It needs the
bridge
to attachRCTTouchHandler
to the container view. The library is written inswift
. https://github.com/lodev09/react-native-true-sheetAny ideas or I'm missing something?
Steps to reproduce
example/app.json
and setnewArchEnabled: true
at line38
React Native Version
0.74.2
Affected Platforms
Runtime - iOS
Areas
Bridgeless - The New Initialization Flow
Output of
npx react-native info
Stacktrace or Logs
Reproducer
https://github.com/lodev09/react-native-true-sheet/tree/main/example
Screenshots and Videos