Skip to content

Commit

Permalink
Native changes for visionOS
Browse files Browse the repository at this point in the history
  • Loading branch information
Saadnajmi committed Jan 26, 2024
1 parent 8c77eef commit 0ff2a98
Show file tree
Hide file tree
Showing 35 changed files with 203 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,11 @@ - (void)applicationDidFinishLaunching:(NSNotification *)notification
rootView = [self createRootViewWithBridge:self.bridge moduleName:self.moduleName initProps:initProps];
}
#if !TARGET_OS_OSX // [macOS]
#if !TARGET_OS_VISION // [visionOS]
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
#else
self.window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 1280, 720)];
#endif // [visionOS]
UIViewController *rootViewController = [self createRootViewController];
[self setRootView:rootView toRootViewController:rootViewController];
self.window.rootViewController = rootViewController;
Expand All @@ -142,7 +146,7 @@ - (void)applicationDidFinishLaunching:(NSNotification *)notification

return YES;
#else // [macOS
NSRect frame = NSMakeRect(0,0,1024,768);
NSRect frame = NSMakeRect(0,0,1280,720);
self.window = [[NSWindow alloc] initWithContentRect:NSZeroRect
styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskResizable | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable
backing:NSBackingStoreBuffered
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Pod::Spec.new do |s|
"HEADER_SEARCH_PATHS" => header_search_paths.join(' ')
}
s.ios.frameworks = "MobileCoreServices" # [macOS] Restrict to iOS
s.visionos.frameworks = "MobileCoreServices" # [macOS] Restrict to visonOS

s.dependency "RCT-Folly", folly_version
s.dependency "React-Codegen", version
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ typedef void (^RCTRemoteNotificationCallback)(UIBackgroundFetchResult result);
#if !TARGET_OS_OSX // [macOS]
+ (void)didReceiveRemoteNotification:(NSDictionary *)notification
fetchCompletionHandler:(RCTRemoteNotificationCallback)completionHandler;
#if !TARGET_OS_VISION // [visionOS]
+ (void)didReceiveLocalNotification:(UILocalNotification *)notification;
#endif // [visionOS]
#endif // [macOS]
#if TARGET_OS_OSX // [macOS
+ (void)didReceiveUserNotification:(NSUserNotification *)notification;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ @implementation RCTPushNotificationManager

#if !TARGET_OS_UIKITFORMAC

#if !TARGET_OS_OSX // [macOS]
#if TARGET_OS_IOS // [macOS] [visionOS]
/** DEPRECATED. UILocalNotification was deprecated in iOS 10. Please don't add new callsites. */
static NSDictionary *RCTFormatLocalNotification(UILocalNotification *notification)
{
Expand All @@ -126,7 +126,8 @@ @implementation RCTPushNotificationManager
formattedLocalNotification[@"remote"] = @NO;
return formattedLocalNotification;
}
#else // [macOS
#endif // [macOS] [visionOS]
#if TARGET_OS_OSX // [macOS
static NSDictionary *RCTFormatUserNotification(NSUserNotification *notification)
{
NSMutableDictionary *formattedUserNotification = [NSMutableDictionary dictionary];
Expand Down Expand Up @@ -282,14 +283,15 @@ + (void)didReceiveRemoteNotification:(NSDictionary *)notification
}
#endif // [macOS]

#if !TARGET_OS_OSX // [macOS]
#if TARGET_OS_IOS // [macOS] [visionOS]
+ (void)didReceiveLocalNotification:(UILocalNotification *)notification
{
[[NSNotificationCenter defaultCenter] postNotificationName:kLocalNotificationReceived
object:self
userInfo:RCTFormatLocalNotification(notification)];
}
#else // [macOS
#endif // [macOS] [visionOS]
#if TARGET_OS_OSX // [macOS
+ (void)didReceiveUserNotification:(NSUserNotification *)notification
{
NSString *notificationName = notification.isRemote ? RCTRemoteNotificationReceived : kLocalNotificationReceived;
Expand Down Expand Up @@ -568,7 +570,7 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification
: (RCTPromiseResolveBlock)resolve reject
: (__unused RCTPromiseRejectBlock)reject)
{
#if !TARGET_OS_OSX // [macOS]
#if TARGET_OS_IOS // [macOS] [visionOS]
NSMutableDictionary<NSString *, id> *initialNotification =
[self.bridge.launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] mutableCopy];

Expand All @@ -583,7 +585,8 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification
} else {
resolve((id)kCFNull);
}
#else // [macOS
#endif // [macOS] [visionOS]
#if TARGET_OS_OSX // [macOS
NSUserNotification *initialNotification = self.bridge.launchOptions[NSApplicationLaunchUserNotificationKey];
if (initialNotification) {
resolve(RCTFormatUserNotification(initialNotification));
Expand Down
1 change: 1 addition & 0 deletions packages/react-native/Libraries/Text/React-RCTText.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Pod::Spec.new do |s|
s.preserve_paths = "package.json", "LICENSE", "LICENSE-docs"
s.header_dir = "RCTText"
s.ios.framework = ["MobileCoreServices"] # [macOS] Restrict to iOS
s.visionos.framework = ["MobileCoreServices"] # [macOS] Restrict to iOS
s.pod_target_xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => "c++20" }

s.dependency "Yoga"
Expand Down
39 changes: 19 additions & 20 deletions packages/react-native/Libraries/Text/Text/RCTTextView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -374,27 +374,26 @@ - (void)disableContextMenu
- (void)handleLongPress:(UILongPressGestureRecognizer *)gesture
{
#if !TARGET_OS_UIKITFORMAC
if (@available(iOS 16.0, *)) {
CGPoint location = [gesture locationInView:self];
UIEditMenuConfiguration *config = [UIEditMenuConfiguration configurationWithIdentifier:nil sourcePoint:location];
if (_editMenuInteraction) {
[_editMenuInteraction presentEditMenuWithConfiguration:config];
}
return;
}
// TODO: Adopt showMenuFromRect (necessary for UIKitForMac)
UIMenuController *menuController = [UIMenuController sharedMenuController];

if (menuController.isMenuVisible) {
return;
}

if (!self.isFirstResponder) {
[self becomeFirstResponder];
if (@available(iOS 16.0, macCatalyst 16.0, *)) { // [visionOS]
CGPoint location = [gesture locationInView:self];
UIEditMenuConfiguration *config = [UIEditMenuConfiguration configurationWithIdentifier:nil sourcePoint:location];
if (_editMenuInteraction) {
[_editMenuInteraction presentEditMenuWithConfiguration:config];
// [visionOS
} else {
UIMenuController *menuController = [UIMenuController sharedMenuController];

if (menuController.isMenuVisible) {
return;
}

if (!self.isFirstResponder) {
[self becomeFirstResponder];
}

[menuController showMenuFromView:self rect:self.bounds];
}
}

[menuController setTargetRect:self.bounds inView:self];
[menuController setMenuVisible:YES animated:YES];
#endif
}
#else // [macOS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,7 @@ - (void)didMoveToWindow

#pragma mark - Custom Input Accessory View

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

- (void)setCustomInputAccessoryViewWithNativeID:(NSString *)nativeID
{
#if !TARGET_OS_OSX // [macOS]
__weak RCTBaseTextInputView *weakSelf = self;
[_bridge.uiManager rootViewForReactTag:self.reactTag
withCompletion:^(UIView *rootView) {
Expand All @@ -877,12 +877,10 @@ - (void)setCustomInputAccessoryViewWithNativeID:(NSString *)nativeID
}
}
}];
#endif // [macOS]
}

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

Expand Down Expand Up @@ -914,8 +912,8 @@ - (void)setDefaultInputAccessoryView
textInputView.inputAccessoryView = nil;
}
[self reloadInputViewsIfNecessary];
#endif // [macOS]
}
#endif // [macOS]

#if !TARGET_OS_OSX // [macOS]
- (void)reloadInputViewsIfNecessary
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

// [macOS]

#if TARGET_OS_OSX // [macOS]

#define RCT_SUBCLASS_SECURETEXTFIELD 1

#include <React/RCTUITextField.h>

#endif // [macOS]
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

// [macOS]

#if TARGET_OS_OSX // [macOS]

#define RCT_SUBCLASS_SECURETEXTFIELD 1

#include "../RCTUITextField.mm"

#endif // [macOS]
3 changes: 3 additions & 0 deletions packages/react-native/React/Base/RCTConvert.m
Original file line number Diff line number Diff line change
Expand Up @@ -537,13 +537,16 @@ + (UIKeyboardType)UIKeyboardType:(id)json RCT_DYNAMIC
UIViewContentModeScaleAspectFill,
integerValue)


RCT_ENUM_CONVERTER(
UIBarStyle,
(@{
@"default" : @(UIBarStyleDefault),
@"black" : @(UIBarStyleBlack),
#if !TARGET_OS_VISION // [visionOS]
@"blackOpaque" : @(UIBarStyleBlackOpaque),
@"blackTranslucent" : @(UIBarStyleBlackTranslucent),
#endif // [visionOS]
}),
UIBarStyleDefault,
integerValue)
Expand Down
6 changes: 5 additions & 1 deletion packages/react-native/React/Base/RCTKeyCommands.m
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,11 @@ - (void)handleKeyUIEventSwizzle:(UIEvent *)event
isKeyDown = [event _isKeyDown];
}

BOOL interactionEnabled = !RCTSharedApplication().isIgnoringInteractionEvents;
#if !TARGET_OS_VISION // [visionOS]
BOOL interactionEnabled = !RCTSharedApplication().isIgnoringInteractionEvents;
#else // [visionOS
BOOL interactionEnabled = true;
#endif // visionOS]
BOOL hasFirstResponder = NO;
if (isKeyDown && modifiedInput.length > 0 && interactionEnabled) {
UIResponder *firstResponder = nil;
Expand Down
5 changes: 5 additions & 0 deletions packages/react-native/React/Base/RCTUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ RCT_EXTERN RCTUIApplication *__nullable RCTSharedApplication(void); // [macOS]
// or view controller
RCT_EXTERN RCTUIWindow *__nullable RCTKeyWindow(void); // [macOS]

#if TARGET_OS_VISION // [visionOS
// Returns UIStatusBarManager to get it's configuration info.
RCT_EXTERN UIStatusBarManager *__nullable RCTUIStatusBarManager(void);
#endif // visionOS]

#if !TARGET_OS_OSX // [macOS]
// Returns the presented view controller, useful if you need
// e.g. to present a modal view controller or alert over it
Expand Down
12 changes: 12 additions & 0 deletions packages/react-native/React/Base/RCTUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,11 @@ CGSize RCTScreenSize(void)
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
RCTUnsafeExecuteOnMainQueueSync(^{
#if !TARGET_OS_VISION // [visionOS]
size = [UIScreen mainScreen].bounds.size;
#else // [visionOS
size = RCTKeyWindow().bounds.size;
#endif // visionOS]
});
});

Expand Down Expand Up @@ -620,6 +624,14 @@ BOOL RCTRunningInAppExtension(void)
#endif // macOS]
}

#if TARGET_OS_VISION // [visionOS
UIStatusBarManager *__nullable RCTUIStatusBarManager(void) {
NSSet *connectedScenes = RCTSharedApplication().connectedScenes;
UIWindowScene *windowScene = [connectedScenes anyObject];
return windowScene.statusBarManager;
}
#endif // visionOS]

#if !TARGET_OS_OSX // [macOS]
UIViewController *__nullable RCTPresentedViewController(void)
{
Expand Down
13 changes: 6 additions & 7 deletions packages/react-native/React/CoreModules/RCTDeviceInfo.mm
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,14 @@ - (void)initialize
name:RCTAccessibilityManagerDidUpdateMultiplierNotification
object:[_moduleRegistry moduleForName:"AccessibilityManager"]];

#if TARGET_OS_IOS // [visionOS]
_currentInterfaceOrientation = [RCTSharedApplication() statusBarOrientation];

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(interfaceOrientationDidChange)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];
#endif // [visionOS]
#endif // [macOS]

_currentInterfaceDimensions = [self _exportedDimensions];
Expand Down Expand Up @@ -90,8 +92,8 @@ - (void)invalidate

static BOOL RCTIsIPhoneNotched()
{
#if !TARGET_OS_OSX // [macOS]
static BOOL isIPhoneNotched = NO;
#if TARGET_OS_IOS // [macOS] [visionOS]
static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{
Expand All @@ -100,11 +102,9 @@ static BOOL RCTIsIPhoneNotched()
// 20pt is the top safeArea value in non-notched devices
isIPhoneNotched = RCTSharedApplication().keyWindow.safeAreaInsets.top > 20;
});
#endif // [macOS] [visionOS]

return isIPhoneNotched;
#else // [macOS
return NO;
#endif // macOS]
}


Expand Down Expand Up @@ -182,8 +182,7 @@ - (void)didReceiveNewContentSizeMultiplier
});
}

#if !TARGET_OS_OSX // [macOS]

#if TARGET_OS_IOS // [macOS] [visionOS]
- (void)interfaceOrientationDidChange
{
__weak __typeof(self) weakSelf = self;
Expand Down Expand Up @@ -224,7 +223,7 @@ - (void)_interfaceOrientationDidChange
#pragma clang diagnostic pop
}
}
#endif // [macOS]
#endif // [macOS] [visionOS]

- (void)interfaceFrameDidChange
{
Expand Down
6 changes: 5 additions & 1 deletion packages/react-native/React/CoreModules/RCTPerfMonitor.mm
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,11 @@ - (UIPanGestureRecognizer *)gestureRecognizer
- (UIView *)container
{
if (!_container) {
CGSize statusBarSize = RCTSharedApplication().statusBarFrame.size;
#if !TARGET_OS_VISION // [visionOS]
CGSize statusBarSize = RCTSharedApplication().statusBarFrame.size;
#else // [visionOS
CGSize statusBarSize = RCTUIStatusBarManager().statusBarFrame.size;
#endif // visionOS]
CGFloat statusBarHeight = statusBarSize.height;
_container = [[UIView alloc] initWithFrame:CGRectMake(10, statusBarHeight, 180, RCTPerfMonitorBarHeight)];
_container.layer.borderWidth = 2;
Expand Down
6 changes: 6 additions & 0 deletions packages/react-native/React/CoreModules/RCTRedBox.mm
Original file line number Diff line number Diff line change
Expand Up @@ -953,9 +953,15 @@ - (void)showErrorMessage:(NSString *)message

if (!self->_window) {
#if !TARGET_OS_OSX // [macOS]
#if !TARGET_OS_VISION // [macOS]
self->_window = [[RCTRedBoxWindow alloc] initWithFrame:[UIScreen mainScreen].bounds
customButtonTitles:self->_customButtonTitles
customButtonHandlers:self->_customButtonHandlers];
#else // [visionOS
self->_window = [[RCTRedBoxWindow alloc] initWithFrame:CGRectMake(0, 0, 1000, 1000)
customButtonTitles:self->_customButtonTitles
customButtonHandlers:self->_customButtonHandlers];
#endif // visionOS]
#else // [macOS
self->_window = [RCTRedBoxWindow new];
#endif // macOS]
Expand Down
Loading

0 comments on commit 0ff2a98

Please sign in to comment.