-
Notifications
You must be signed in to change notification settings - Fork 24.7k
[iOS] Turbo module: Fixes dictionary stripped out when value is null #51103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[iOS] Turbo module: Fixes dictionary stripped out when value is null #51103
Conversation
@philIip has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
Hi @zhongwuzw! thanks for the PR. Internally, we have several pieces of code that relies on the null values being removed from the dictionary, so by landing this, we are going to break that code. Similarly, we might be breaking New Arch libraries that do not expect receiving |
@cipolleschi Thanks for the review. If we don't support null vaule of dictionary, we should seems make the native module like setting module add a removeKey api to not passed dictionary? |
Thanks for fixing this! I think this absolutely needs a unit test to show how the behaviour changes before/after. |
@@ -639,6 +639,10 @@ TraceSection s( | |||
// Message dispatch logic from old infra | |||
id (*convert)(id, SEL, id) = (__typeof__(convert))objc_msgSend; | |||
id convertedObjCArg = convert([RCTConvert class], rctConvertSelector, objCArg); | |||
|
|||
if (objCArg == [NSNull null]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be looking at convertedObjCArg
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I keep the same logic as RCTInteropTurboModule
: ) https://github.com/facebook/react-native/blob/main/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTInteropTurboModule.mm#L475-L483 .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zhongwuzw: that doesn't seem right. RCTInteropTurboModule looks at arg
, which is the return value of the RCTConvertTo
call (we should probably use that RCTConvertTo helper here too!) - so the equivalent would be to use convertedObjCArg
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, you're right. 👍 updated.
As @javache was mentioning, we discussed this internally and we want to pull in the fix.
Do you mind applying these changes? |
@cipolleschi Got it. I'll try to do them. |
I tried to apply this fix to a test that I was doing for #51083, but it does not fixes. It contains both a legacy native module and a turbomodule. The expectation is that both should receive {
"key": "myKey",
"value": "<null>"
} when pressing the |
@cipolleschi Hi, I tried, seems I received the null value. BTW, can you help me how to write a test? I don't know wether unit test needs some env requirements? Seems I only see the old bridge related unit test. I used RNTester RNTesterUnitTests schema. |
This reverts commit f09fced.
…/fix_dictionary_not_passed_nil_value
id objCArg = convertJSIValueToObjCObject(runtime, arg, jsInvoker_); | ||
BOOL enableModuleArgumentNSNullConversionIOS = ReactNativeFeatureFlags::enableModuleArgumentNSNullConversionIOS(); | ||
id objCArg = TurboModuleConvertUtils::convertJSIValueToObjCObject( | ||
runtime, arg, jsInvoker_, enableModuleArgumentNSNullConversionIOS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we passing enableModuleArgumentNSNullConversionIOS
to the convertJSIValueToObjCObject
function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We enable useNull only if we set enableModuleArgumentNSNullConversionIOS to true to convert null to NSNull. If we don't enable enableModuleArgumentNSNullConversionIOS, everything remains the same as original.
~~I tried again with the repo I prepared and I don't get the same result as you. 😰 ~~ My bad, I realized that I applied badly your suggestion. For the unit test, I'm not sure we have something set up in OSS. I'll have to investigate a bit and get back to you. |
I'm adding a test in #51370 - which we should be able to use verify this changes fixes it once you enable the feature flag. |
…/fix_dictionary_not_passed_nil_value
Can you update the test and add a variant that shows the behaviour you get when overriding the feature flag? |
Summary:
Fixes #51083. Turbo stripped out the dictionary when the value is null. The old architecture transforms null to NSNull. The null seems useful in cases like #51803 for removing the storage of the key. @cipolleschi can you please help to review?
Changelog:
[IOS] [FIXED] - Turbo module: Fixes dictionary stripped out when value is null
Test Plan:
Repro please see #51083.