Skip to content

Commit 7243805

Browse files
committed
Add visionOS support (microsoft#2019)
* Remove TARGET_OS_UIKITFORMAC macros (facebook#42278) Summary: There seems to be a lot of `TARGET_OS_UIKITFORMAC` macro in React Native that don't need to be there. Let's remove them. First off, what is `TARGET_OS_UIKITFORMAC` targeting? You might think it's [Mac Catalyst](https://developer.apple.com/mac-catalyst/), if you look at the [commit](facebook@3724810) introducing the ifdefs. However.. that doesn't seem right because `TARGET_OS_MACCATALYST` exists, and is used elsewhere in the codebase. In fact, if you look at this handy comment inside `TargetConditionals.h` (the file that defines all these conditionals), `TARGET_OS_UIKITFORMAC` is not even on there! ``` /* * TARGET_OS_* * * These conditionals specify in which Operating System the generated code will * run. Indention is used to show which conditionals are evolutionary subclasses. * * The MAC/WIN32/UNIX conditionals are mutually exclusive. * The IOS/TV/WATCH/VISION conditionals are mutually exclusive. * * TARGET_OS_WIN32 - Generated code will run on WIN32 API * TARGET_OS_WINDOWS - Generated code will run on Windows * TARGET_OS_UNIX - Generated code will run on some Unix (not macOS) * TARGET_OS_LINUX - Generated code will run on Linux * TARGET_OS_MAC - Generated code will run on a variant of macOS * TARGET_OS_OSX - Generated code will run on macOS * TARGET_OS_IPHONE - Generated code will run on a variant of iOS (firmware, devices, simulator) * TARGET_OS_IOS - Generated code will run on iOS * TARGET_OS_MACCATALYST - Generated code will run on macOS * TARGET_OS_TV - Generated code will run on tvOS * TARGET_OS_WATCH - Generated code will run on watchOS * TARGET_OS_VISION - Generated code will run on visionOS * TARGET_OS_BRIDGE - Generated code will run on bridge devices * TARGET_OS_SIMULATOR - Generated code will run on an iOS, tvOS, watchOS, or visionOS simulator * TARGET_OS_DRIVERKIT - Generated code will run on macOS, iOS, tvOS, watchOS, or visionOS * * TARGET_OS_EMBEDDED - DEPRECATED: Use TARGET_OS_IPHONE and/or TARGET_OS_SIMULATOR instead * TARGET_IPHONE_SIMULATOR - DEPRECATED: Same as TARGET_OS_SIMULATOR * TARGET_OS_NANO - DEPRECATED: Same as TARGET_OS_WATCH * * +--------------------------------------------------------------------------------------+ * | TARGET_OS_MAC | * | +-----+ +------------------------------------------------------------+ +-----------+ | * | | | | TARGET_OS_IPHONE | | | | * | | | | +-----------------+ +----+ +-------+ +--------+ +--------+ | | | | * | | | | | IOS | | | | | | | | | | | | | * | | OSX | | | +-------------+ | | TV | | WATCH | | BRIDGE | | VISION | | | DRIVERKIT | | * | | | | | | MACCATALYST | | | | | | | | | | | | | | * | | | | | +-------------+ | | | | | | | | | | | | | * | | | | +-----------------+ +----+ +-------+ +--------+ +--------+ | | | | * | +-----+ +------------------------------------------------------------+ +-----------+ | * +--------------------------------------------------------------------------------------+ */ ``` Going even deeper into `TargetConditionals.h`, you will see `TARGET_OS_UIKITFORMAC` defined... and it's always 1 when `TARGET_OS_MACCATALYST` is 1, making it feel even more redundant. My current conclusion is it's either another variant of Mac Catalyst (the one where they just run unmodified UIKit maybe..), or it's an older macro back from when Catalyst was still experimental. Either way, it's pretty obvious nobody is running or testing this codepath, and it adds bloat, especially to React Native macOS where we have extra ifdef blocks for macOS support (and eventually visionOS support). Let's remove it. Another change I made while we're here: I've seen this lingering TODO to replace setTargetRect:InView: / setMenuVisible:animated: (deprecated as of iOS 13, below our minimum OS requirement) with showMenuFromView (deprecated as of iOS 16, in line with the availability check). Let's just.... do that? [IOS] [REMOVED] - Remove TARGET_OS_UIKITFORMAC macros Pull Request resolved: facebook#42278 Test Plan: RNTester with Mac Catalyst still compiles: ![Screenshot 2024-01-15 at 12 26 03 AM](https://github.com/facebook/react-native/assets/6722175/015bd37d-f536-43c7-9586-96187cdbd013) Reviewed By: cipolleschi Differential Revision: D52780690 Pulled By: sammy-SC fbshipit-source-id: df6a333e8e15f79de0ce6f538ebd73b92698dcb6 * Remove an early return to suppress a deprecated API warning for `UIMenuController` (facebook#42277) Summary: `UIMenuController` is deprecated as of iOS 16. facebook@e08a197 migrated a usage into an `available` check. However, it does not properly fall back to the deprecated API in the "else" block of the availability check, instead it uses an early return. It seems this means Xcode still sees the API as used, and spits out a deprecated warning. Let's just refactor the code so we don't have that anymore. [IOS] [FIXED] - Remove an early return to suppress a deprecated API warning for `UIMenuController` Pull Request resolved: facebook#42277 Test Plan: CI should pass. Reviewed By: cipolleschi Differential Revision: D52785488 Pulled By: sammy-SC fbshipit-source-id: 0b47e8aa8d7c94728e3d68332fbb8f97f8ded34e * Native changes for visionOS
1 parent 0b66dea commit 7243805

36 files changed

+240
-208
lines changed

packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,11 @@ - (void)applicationDidFinishLaunching:(NSNotification *)notification
129129
rootView = [self createRootViewWithBridge:self.bridge moduleName:self.moduleName initProps:initProps];
130130
}
131131
#if !TARGET_OS_OSX // [macOS]
132+
#if !TARGET_OS_VISION // [visionOS]
132133
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
134+
#else
135+
self.window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 1280, 720)];
136+
#endif // [visionOS]
133137
UIViewController *rootViewController = [self createRootViewController];
134138
[self setRootView:rootView toRootViewController:rootViewController];
135139
self.window.rootViewController = rootViewController;
@@ -138,7 +142,7 @@ - (void)applicationDidFinishLaunching:(NSNotification *)notification
138142

139143
return YES;
140144
#else // [macOS
141-
NSRect frame = NSMakeRect(0,0,1024,768);
145+
NSRect frame = NSMakeRect(0,0,1280,720);
142146
self.window = [[NSWindow alloc] initWithContentRect:NSZeroRect
143147
styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskResizable | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable
144148
backing:NSBackingStoreBuffered

packages/react-native/Libraries/Image/RCTUIImageViewAnimated.mm

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -193,15 +193,10 @@ - (BOOL)paused
193193

194194
- (void)displayDidRefresh:(CADisplayLink *)displayLink
195195
{
196-
#if TARGET_OS_UIKITFORMAC
197-
// TODO: `displayLink.frameInterval` is not available on UIKitForMac
198-
NSTimeInterval durationToNextRefresh = displayLink.duration;
199-
#else
200196
// displaylink.duration -- time interval between frames, assuming maximumFramesPerSecond
201197
// displayLink.preferredFramesPerSecond (>= iOS 10) -- Set to 30 for displayDidRefresh to be called at 30 fps
202198
// durationToNextRefresh -- Time interval to the next time displayDidRefresh is called
203199
NSTimeInterval durationToNextRefresh = displayLink.targetTimestamp - displayLink.timestamp;
204-
#endif
205200
NSUInteger totalFrameCount = self.totalFrameCount;
206201
NSUInteger currentFrameIndex = self.currentFrameIndex;
207202
NSUInteger nextFrameIndex = (currentFrameIndex + 1) % totalFrameCount;

packages/react-native/Libraries/Network/React-RCTNetwork.podspec

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ Pod::Spec.new do |s|
4242
"CLANG_CXX_LANGUAGE_STANDARD" => "c++20",
4343
"HEADER_SEARCH_PATHS" => header_search_paths.join(' ')
4444
}
45-
s.ios.frameworks = "MobileCoreServices" # [macOS] Restrict to iOS
45+
# [macOS MobileCoreServices Not available on macOS
46+
s.ios.frameworks = "MobileCoreServices"
47+
s.visionos.frameworks = "MobileCoreServices"
48+
# macOS]
4649

4750
s.dependency "RCT-Folly", folly_version
4851
s.dependency "RCTTypeSafety"

packages/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,18 @@ extern NSString *const RCTRemoteNotificationReceived;
1515
typedef void (^RCTRemoteNotificationCallback)(UIBackgroundFetchResult result);
1616
#endif // [macOS]
1717

18-
#if !TARGET_OS_UIKITFORMAC
1918
+ (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
2019
+ (void)didReceiveRemoteNotification:(NSDictionary *)notification;
2120
#if !TARGET_OS_OSX // [macOS]
2221
+ (void)didReceiveRemoteNotification:(NSDictionary *)notification
2322
fetchCompletionHandler:(RCTRemoteNotificationCallback)completionHandler;
23+
#if TARGET_OS_IOS // [visionOS]
2424
+ (void)didReceiveLocalNotification:(UILocalNotification *)notification;
25+
#endif // [visionOS]
2526
#endif // [macOS]
2627
#if TARGET_OS_OSX // [macOS
2728
+ (void)didReceiveUserNotification:(NSUserNotification *)notification;
2829
#endif // macOS]
2930
+ (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error;
30-
#endif
3131

3232
@end

packages/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm

Lines changed: 9 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424

2525
static NSString *const kErrorUnableToRequestPermissions = @"E_UNABLE_TO_REQUEST_PERMISSIONS";
2626

27-
#if !TARGET_OS_UIKITFORMAC
28-
2927
@interface RCTPushNotificationManager () <NativePushNotificationManagerIOSSpec>
3028
@property (nonatomic, strong) NSMutableDictionary *remoteNotificationCallbacks;
3129
@end
@@ -97,16 +95,10 @@ @implementation RCTConvert (UIBackgroundFetchResult)
9795

9896
@end
9997
#endif // [macOS]
100-
#else
101-
@interface RCTPushNotificationManager () <NativePushNotificationManagerIOSSpec>
102-
@end
103-
#endif // TARGET_OS_UIKITFORMAC
10498

10599
@implementation RCTPushNotificationManager
106100

107-
#if !TARGET_OS_UIKITFORMAC
108-
109-
#if !TARGET_OS_OSX // [macOS]
101+
#if TARGET_OS_IOS // [macOS] [visionOS]
110102
/** DEPRECATED. UILocalNotification was deprecated in iOS 10. Please don't add new callsites. */
111103
static NSDictionary *RCTFormatLocalNotification(UILocalNotification *notification)
112104
{
@@ -126,7 +118,8 @@ @implementation RCTPushNotificationManager
126118
formattedLocalNotification[@"remote"] = @NO;
127119
return formattedLocalNotification;
128120
}
129-
#else // [macOS
121+
#endif // [macOS] [visionOS]
122+
#if TARGET_OS_OSX // [macOS
130123
static NSDictionary *RCTFormatUserNotification(NSUserNotification *notification)
131124
{
132125
NSMutableDictionary *formattedUserNotification = [NSMutableDictionary dictionary];
@@ -198,16 +191,13 @@ @implementation RCTPushNotificationManager
198191
return [formatter stringFromDate:date];
199192
}
200193

201-
#endif // TARGET_OS_UIKITFORMAC
202-
203194
RCT_EXPORT_MODULE()
204195

205196
- (dispatch_queue_t)methodQueue
206197
{
207198
return dispatch_get_main_queue();
208199
}
209200

210-
#if !TARGET_OS_UIKITFORMAC
211201
- (void)startObserving
212202
{
213203
[[NSNotificationCenter defaultCenter] addObserver:self
@@ -282,14 +272,15 @@ + (void)didReceiveRemoteNotification:(NSDictionary *)notification
282272
}
283273
#endif // [macOS]
284274

285-
#if !TARGET_OS_OSX // [macOS]
275+
#if TARGET_OS_IOS // [macOS] [visionOS]
286276
+ (void)didReceiveLocalNotification:(UILocalNotification *)notification
287277
{
288278
[[NSNotificationCenter defaultCenter] postNotificationName:kLocalNotificationReceived
289279
object:self
290280
userInfo:RCTFormatLocalNotification(notification)];
291281
}
292-
#else // [macOS
282+
#endif // [macOS] [visionOS]
283+
#if TARGET_OS_OSX // [macOS
293284
+ (void)didReceiveUserNotification:(NSUserNotification *)notification
294285
{
295286
NSString *notificationName = notification.isRemote ? RCTRemoteNotificationReceived : kLocalNotificationReceived;
@@ -568,7 +559,7 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification
568559
: (RCTPromiseResolveBlock)resolve reject
569560
: (__unused RCTPromiseRejectBlock)reject)
570561
{
571-
#if !TARGET_OS_OSX // [macOS]
562+
#if TARGET_OS_IOS // [macOS] [visionOS]
572563
NSMutableDictionary<NSString *, id> *initialNotification =
573564
[self.bridge.launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] mutableCopy];
574565

@@ -583,7 +574,8 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification
583574
} else {
584575
resolve((id)kCFNull);
585576
}
586-
#else // [macOS
577+
#endif // [macOS] [visionOS]
578+
#if TARGET_OS_OSX // [macOS
587579
NSUserNotification *initialNotification = self.bridge.launchOptions[NSApplicationLaunchUserNotificationKey];
588580
if (initialNotification) {
589581
resolve(RCTFormatUserNotification(initialNotification));
@@ -638,100 +630,6 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification
638630
}];
639631
}
640632

641-
#else // TARGET_OS_UIKITFORMAC
642-
643-
RCT_EXPORT_METHOD(onFinishRemoteNotification : (NSString *)notificationId fetchResult : (NSString *)fetchResult)
644-
{
645-
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
646-
}
647-
648-
RCT_EXPORT_METHOD(setApplicationIconBadgeNumber : (double)number)
649-
{
650-
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
651-
}
652-
653-
RCT_EXPORT_METHOD(getApplicationIconBadgeNumber : (RCTResponseSenderBlock)callback)
654-
{
655-
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
656-
}
657-
658-
RCT_EXPORT_METHOD(requestPermissions
659-
: (JS::NativePushNotificationManagerIOS::SpecRequestPermissionsPermission &)permissions resolve
660-
: (RCTPromiseResolveBlock)resolve reject
661-
: (RCTPromiseRejectBlock)reject)
662-
{
663-
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
664-
}
665-
666-
RCT_EXPORT_METHOD(abandonPermissions)
667-
{
668-
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
669-
}
670-
671-
RCT_EXPORT_METHOD(checkPermissions : (RCTResponseSenderBlock)callback)
672-
{
673-
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
674-
}
675-
676-
RCT_EXPORT_METHOD(presentLocalNotification : (JS::NativePushNotificationManagerIOS::Notification &)notification)
677-
{
678-
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
679-
}
680-
681-
RCT_EXPORT_METHOD(scheduleLocalNotification : (JS::NativePushNotificationManagerIOS::Notification &)notification)
682-
{
683-
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
684-
}
685-
686-
RCT_EXPORT_METHOD(cancelAllLocalNotifications)
687-
{
688-
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
689-
}
690-
691-
RCT_EXPORT_METHOD(cancelLocalNotifications : (NSDictionary<NSString *, id> *)userInfo)
692-
{
693-
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
694-
}
695-
696-
RCT_EXPORT_METHOD(getInitialNotification
697-
: (RCTPromiseResolveBlock)resolve reject
698-
: (__unused RCTPromiseRejectBlock)reject)
699-
{
700-
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
701-
}
702-
703-
RCT_EXPORT_METHOD(getScheduledLocalNotifications : (RCTResponseSenderBlock)callback)
704-
{
705-
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
706-
}
707-
708-
RCT_EXPORT_METHOD(removeAllDeliveredNotifications)
709-
{
710-
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
711-
}
712-
713-
RCT_EXPORT_METHOD(removeDeliveredNotifications : (NSArray<NSString *> *)identifiers)
714-
{
715-
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
716-
}
717-
718-
RCT_EXPORT_METHOD(getDeliveredNotifications : (RCTResponseSenderBlock)callback)
719-
{
720-
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
721-
}
722-
723-
RCT_EXPORT_METHOD(getAuthorizationStatus : (RCTResponseSenderBlock)callback)
724-
{
725-
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
726-
}
727-
728-
- (NSArray<NSString *> *)supportedEvents
729-
{
730-
return @[];
731-
}
732-
733-
#endif // TARGET_OS_UIKITFORMAC
734-
735633
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
736634
(const facebook::react::ObjCTurboModule::InitParams &)params
737635
{

packages/react-native/Libraries/Text/React-RCTText.podspec

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ Pod::Spec.new do |s|
3030
s.ios.exclude_files = "**/macOS/*" # [macOS]
3131
s.preserve_paths = "package.json", "LICENSE", "LICENSE-docs"
3232
s.header_dir = "RCTText"
33-
s.ios.framework = ["MobileCoreServices"] # [macOS] Restrict to iOS
33+
# [macOS MobileCoreServices Not available on macOS
34+
s.ios.frameworks = "MobileCoreServices"
35+
s.visionos.frameworks = "MobileCoreServices"
36+
# macOS]
3437
s.pod_target_xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => "c++20" }
3538

3639
s.dependency "Yoga"

packages/react-native/Libraries/Text/Text/RCTTextView.mm

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -373,29 +373,21 @@ - (void)disableContextMenu
373373

374374
- (void)handleLongPress:(UILongPressGestureRecognizer *)gesture
375375
{
376-
#if !TARGET_OS_UIKITFORMAC
377-
if (@available(iOS 16.0, *)) {
376+
if (@available(iOS 16.0, macCatalyst 16.0, *)) {
378377
CGPoint location = [gesture locationInView:self];
379378
UIEditMenuConfiguration *config = [UIEditMenuConfiguration configurationWithIdentifier:nil sourcePoint:location];
380379
if (_editMenuInteraction) {
381380
[_editMenuInteraction presentEditMenuWithConfiguration:config];
382381
}
383-
return;
384-
}
385-
// TODO: Adopt showMenuFromRect (necessary for UIKitForMac)
386-
UIMenuController *menuController = [UIMenuController sharedMenuController];
382+
} else {
383+
UIMenuController *menuController = [UIMenuController sharedMenuController];
387384

388-
if (menuController.isMenuVisible) {
389-
return;
390-
}
385+
if (menuController.isMenuVisible) {
386+
return;
387+
}
391388

392-
if (!self.isFirstResponder) {
393-
[self becomeFirstResponder];
389+
[menuController showMenuFromView:self rect:self.bounds];
394390
}
395-
396-
[menuController setTargetRect:self.bounds inView:self];
397-
[menuController setMenuVisible:YES animated:YES];
398-
#endif
399391
}
400392
#else // [macOS
401393

packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,7 @@ - (void)didMoveToWindow
851851

852852
#pragma mark - Custom Input Accessory View
853853

854+
#if TARGET_OS_IOS // [macOS] [visionOS]
854855
- (void)didSetProps:(NSArray<NSString *> *)changedProps
855856
{
856857
if ([changedProps containsObject:@"inputAccessoryViewID"] && self.inputAccessoryViewID) {
@@ -862,7 +863,6 @@ - (void)didSetProps:(NSArray<NSString *> *)changedProps
862863

863864
- (void)setCustomInputAccessoryViewWithNativeID:(NSString *)nativeID
864865
{
865-
#if !TARGET_OS_OSX // [macOS]
866866
__weak RCTBaseTextInputView *weakSelf = self;
867867
[_bridge.uiManager rootViewForReactTag:self.reactTag
868868
withCompletion:^(UIView *rootView) {
@@ -877,12 +877,10 @@ - (void)setCustomInputAccessoryViewWithNativeID:(NSString *)nativeID
877877
}
878878
}
879879
}];
880-
#endif // [macOS]
881880
}
882881

883882
- (void)setDefaultInputAccessoryView
884883
{
885-
#if !TARGET_OS_OSX // [macOS]
886884
UIView<RCTBackedTextInputViewProtocol> *textInputView = self.backedTextInputView;
887885
UIKeyboardType keyboardType = textInputView.keyboardType;
888886

@@ -914,10 +912,8 @@ - (void)setDefaultInputAccessoryView
914912
textInputView.inputAccessoryView = nil;
915913
}
916914
[self reloadInputViewsIfNecessary];
917-
#endif // [macOS]
918915
}
919916

920-
#if !TARGET_OS_OSX // [macOS]
921917
- (void)reloadInputViewsIfNecessary
922918
{
923919
// We have to call `reloadInputViews` for focused text inputs to update an accessory view.
@@ -934,7 +930,7 @@ - (void)handleInputAccessoryDoneButton
934930
[self.backedTextInputView endEditing:YES];
935931
}
936932
}
937-
#endif // [macOS]
933+
#endif // [macOS] [visionOS]
938934

939935
// [macOS
940936

packages/react-native/Libraries/Text/TextInput/Singleline/macOS/RCTUISecureTextField.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77

88
// [macOS]
99

10+
#if TARGET_OS_OSX
1011
#define RCT_SUBCLASS_SECURETEXTFIELD 1
12+
#endif
1113

1214
#include <React/RCTUITextField.h>
15+

packages/react-native/Libraries/Text/TextInput/Singleline/macOS/RCTUISecureTextField.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
// [macOS]
99

10+
#if TARGET_OS_OSX
1011
#define RCT_SUBCLASS_SECURETEXTFIELD 1
12+
#endif
1113

1214
#include "../RCTUITextField.mm"

0 commit comments

Comments
 (0)