Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion ios/RNCPicker.mm
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
*/

#import "RNCPicker.h"
#ifdef RCT_NEW_ARCH_ENABLED
#import "RNCPickerFabricConversions.h"
#endif

#import <React/RCTConvert.h>
#import <React/RCTUtils.h>
Expand Down Expand Up @@ -170,7 +173,7 @@ - (void)pickerView:(__unused UIPickerView *)pickerView
std::dynamic_pointer_cast<const facebook::react::RNCPickerEventEmitter>(eventEmitter)
->onChange(facebook::react::RNCPickerEventEmitter::OnChange{
.newIndex = (int)row,
.newValue = RCTStringFromNSString(_items[row][@"value"]),
.newValue = RNCPickerRNCPickerConvertIdToFollyDynamic(_items[row][@"value"]),
});
}
}
Expand Down
5 changes: 3 additions & 2 deletions ios/RNCPickerComponentView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#import "RNCPickerComponentView.h"
#import "RNCPicker.h"
#import "RNCPickerFabricConversions.h"

#import <React/RCTFabricComponentsPlugins.h>
#import <react/renderer/components/rnpicker/ComponentDescriptors.h>
Expand Down Expand Up @@ -54,8 +55,8 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &
for (RNCPickerItemsStruct item : newProps.items)
{
NSMutableDictionary *dictItem = [NSMutableDictionary new];
dictItem[@"value"] = RCTNSStringFromString(item.value);
dictItem[@"label"] = RCTNSStringFromStringNilIfEmpty(item.label);
dictItem[@"value"] = RNCPickerConvertFollyDynamicToId(item.value);
dictItem[@"label"] = RNCPickerConvertFollyDynamicToId(item.label);
dictItem[@"textColor"] = RCTUIColorFromSharedColor(item.textColor);
dictItem[@"testID"] = RCTNSStringFromStringNilIfEmpty(item.testID);
[items addObject:dictItem];
Expand Down
106 changes: 106 additions & 0 deletions ios/RNCPickerFabricConversions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#import <folly/dynamic.h>
#import <Foundation/Foundation.h>
#import <objc/runtime.h>

// copied from RCTFollyConvert
static id RNCPickerConvertFollyDynamicToId(const folly::dynamic &dyn)
{
// I could imagine an implementation which avoids copies by wrapping the
// dynamic in a derived class of NSDictionary. We can do that if profiling
// implies it will help.

switch (dyn.type()) {
case folly::dynamic::NULLT:
return nil;
case folly::dynamic::BOOL:
return dyn.getBool() ? @YES : @NO;
case folly::dynamic::INT64:
return @(dyn.getInt());
case folly::dynamic::DOUBLE:
return @(dyn.getDouble());
case folly::dynamic::STRING:
return [[NSString alloc] initWithBytes:dyn.c_str() length:dyn.size() encoding:NSUTF8StringEncoding];
case folly::dynamic::ARRAY: {
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:dyn.size()];
for (const auto &elem : dyn) {
id value = RNCPickerConvertFollyDynamicToId(elem);
if (value) {
[array addObject:value];
}
}
return array;
}
case folly::dynamic::OBJECT: {
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:dyn.size()];
for (const auto &elem : dyn.items()) {
id key = RNCPickerConvertFollyDynamicToId(elem.first);
id value = RNCPickerConvertFollyDynamicToId(elem.second);
if (key && value) {
dict[key] = value;
}
}
return dict;
}
}
}

static folly::dynamic RNCPickerRNCPickerConvertIdToFollyDynamic(id json)
{
if (json == nil || json == (id)kCFNull) {
return nullptr;
} else if ([json isKindOfClass:[NSNumber class]]) {
const char *objCType = [json objCType];
switch (objCType[0]) {
// This is a c++ bool or C99 _Bool. On some platforms, BOOL is a bool.
case _C_BOOL:
return (bool)[json boolValue];
case _C_CHR:
// On some platforms, objc BOOL is a signed char, but it
// might also be a small number. Use the same hack JSC uses
// to distinguish them:
// https://phabricator.intern.facebook.com/diffusion/FBS/browse/master/fbobjc/xplat/third-party/jsc/safari-600-1-4-17/JavaScriptCore/API/JSValue.mm;b8ee03916489f8b12143cd5c0bca546da5014fc9$901
if ([json isKindOfClass:[@YES class]]) {
return (bool)[json boolValue];
} else {
return [json longLongValue];
}
case _C_UCHR:
case _C_SHT:
case _C_USHT:
case _C_INT:
case _C_UINT:
case _C_LNG:
case _C_ULNG:
case _C_LNG_LNG:
case _C_ULNG_LNG:
return [json longLongValue];

case _C_FLT:
case _C_DBL:
return [json doubleValue];

// default:
// fall through
}
} else if ([json isKindOfClass:[NSString class]]) {
NSData *data = [json dataUsingEncoding:NSUTF8StringEncoding];
return std::string(reinterpret_cast<const char *>(data.bytes), data.length);
} else if ([json isKindOfClass:[NSArray class]]) {
folly::dynamic array = folly::dynamic::array;
for (id element in json) {
array.push_back(RNCPickerRNCPickerConvertIdToFollyDynamic(element));
}
return array;
} else if ([json isKindOfClass:[NSDictionary class]]) {
__block folly::dynamic object = folly::dynamic::object();

[json enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, __unused BOOL *stop) {
object.insert(RNCPickerRNCPickerConvertIdToFollyDynamic(key), RNCPickerRNCPickerConvertIdToFollyDynamic(value));
}];

return object;
}

return nil;
}

8 changes: 4 additions & 4 deletions js/PickerIOS.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,12 @@ const PickerIOSWithForwardedRef: React.AbstractComponent<
if (child === null) {
return null;
}
if (String(child.props.value) === String(selectedValue)) {
if (child.props.value === selectedValue) {
selectedIndex = index;
}
return {
value: String(child.props.value),
label: String(child.props.label),
value: child.props.value,
label: child.props.label,
textColor: processColor(child.props.color),
testID: child.props.testID,
};
Expand All @@ -162,7 +162,7 @@ const PickerIOSWithForwardedRef: React.AbstractComponent<
child: $FlowFixMe,
index: number,
) {
if (String(child.props.value) === String(selectedValue)) {
if (child.props.value === selectedValue) {
jsValue = index;
}
});
Expand Down
6 changes: 3 additions & 3 deletions js/RNCPickerNativeComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNati
import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands';

type PickerIOSChangeEvent = $ReadOnly<{|
newValue: string,
newValue: UnsafeMixed,
newIndex: Int32,
|}>;

type RNCPickerIOSTypeItemType = $ReadOnly<{|
label: ?string,
value: ?string,
label: ?UnsafeMixed,
value: ?UnsafeMixed,
textColor: ?ColorValue,
testID: ?string,
|}>;
Expand Down
Loading