diff --git a/.github/workflows/test-all.yml b/.github/workflows/test-all.yml index a4e1c92f3a602e..aa5568915a3a91 100644 --- a/.github/workflows/test-all.yml +++ b/.github/workflows/test-all.yml @@ -1,12 +1,14 @@ name: Test All -on: - workflow_dispatch: - pull_request: - push: - branches: - - main - - "*-stable" +# on: +# workflow_dispatch: +# pull_request: +# push: +# tags: +# - 'v*' +# # nightly build @ 2:15 AM UTC +# schedule: +# - cron: '15 2 * * *' concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/README.md b/README.md index fe5b8e5e1b2103..d1c7aba05cae5f 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ The source for the React Native visionOS documentation and website is hosted on Prerequisites: - Download the latest Xcode (at least 15.2) -- Install the latest version of CMake (at least v3.28.0) +- Install the latest version of CMake (at least v3.29.0) Check out `rn-tester` [README.md](./packages/rn-tester/README.md) to build React Native from the source. diff --git a/packages/helloworld/package.json b/packages/helloworld/package.json index cb1b89bd53c561..113d76e86c9d14 100644 --- a/packages/helloworld/package.json +++ b/packages/helloworld/package.json @@ -13,7 +13,8 @@ }, "dependencies": { "react": "18.3.1", - "react-native": "0.76.0" + "react-native": "0.76.0", + "@callstack/react-native-visionos": "0.76.0-rc.0" }, "devDependencies": { "@babel/core": "^7.25.2", diff --git a/packages/out-of-tree-platforms/package.json b/packages/out-of-tree-platforms/package.json index ee09627611fd41..5053c7a7948799 100644 --- a/packages/out-of-tree-platforms/package.json +++ b/packages/out-of-tree-platforms/package.json @@ -1,6 +1,6 @@ { "name": "@callstack/out-of-tree-platforms", - "version": "0.75.0-main", + "version": "0.76.0-main", "description": "Utils for React Native out of tree platforms.", "keywords": ["out-of-tree", "react-native"], "homepage": "https://github.com/callstack/react-native-visionos/tree/HEAD/packages/out-of-tree-platforms#readme", diff --git a/packages/react-native-test-library/package.json b/packages/react-native-test-library/package.json index 74e22b317433a9..3141b569507347 100644 --- a/packages/react-native-test-library/package.json +++ b/packages/react-native-test-library/package.json @@ -27,7 +27,8 @@ "devDependencies": { "@babel/core": "^7.25.2", "@react-native/babel-preset": "0.76.0", - "react-native": "0.76.0" + "react-native": "0.76.0", + "@callstack/react-native-visionos": "0.76.0-rc.0" }, "peerDependencies": { "react": "*", diff --git a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h index f9ca86a602aea7..cbcb0df0cde3f2 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h +++ b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h @@ -59,7 +59,9 @@ NS_ASSUME_NONNULL_BEGIN /// The window object, used to render the UViewControllers @property (nonatomic, strong, nonnull) UIWindow *window; -@property (nonatomic, nullable) RCTBridge *bridge; +/// Store last focused window to properly handle multi-window scenarios +@property (nonatomic, weak, nullable) UIWindow *lastFocusedWindow; +@property (nonatomic, strong, nullable) RCTBridge *bridge; @property (nonatomic, strong, nullable) NSString *moduleName; @property (nonatomic, strong, nullable) NSDictionary *initialProps; @property (nonatomic, strong, nonnull) RCTRootViewFactory *rootViewFactory; diff --git a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm index 35c1d2d94f6a80..e5979abc0e15d3 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm +++ b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm @@ -62,26 +62,9 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( [RCTComponentViewFactory currentComponentViewFactory].thirdPartyFabricComponentsProvider = self; } - if (self.automaticallyLoadReactNativeWindow) { - [self loadReactNativeWindow:launchOptions]; - } - return YES; } -- (void)loadReactNativeWindow:(NSDictionary *)launchOptions -{ - UIView *rootView = [self.rootViewFactory viewWithModuleName:self.moduleName - initialProperties:self.initialProps - launchOptions:launchOptions]; - - self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; - UIViewController *rootViewController = [self createRootViewController]; - [self setRootView:rootView toRootViewController:rootViewController]; - _window.rootViewController = rootViewController; - [_window makeKeyAndVisible]; -} - - (void)applicationDidEnterBackground:(UIApplication *)application { // Noop @@ -106,7 +89,11 @@ - (UIView *)createRootViewWithBridge:(RCTBridge *)bridge BOOL enableFabric = self.fabricEnabled; UIView *rootView = RCTAppSetupDefaultRootView(bridge, moduleName, initProps, enableFabric); +#if TARGET_OS_VISION + rootView.backgroundColor = [UIColor clearColor]; +#else rootView.backgroundColor = [UIColor systemBackgroundColor]; +#endif return rootView; } diff --git a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm index 80e9fabd1879c9..07a29a0be6f1c7 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm +++ b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm @@ -163,7 +163,11 @@ - (UIView *)viewWithModuleName:(NSString *)moduleName initWithSurface:surface sizeMeasureMode:RCTSurfaceSizeMeasureModeWidthExact | RCTSurfaceSizeMeasureModeHeightExact]; +#if TARGET_OS_VISION + surfaceHostingProxyRootView.backgroundColor = [UIColor clearColor]; +#else surfaceHostingProxyRootView.backgroundColor = [UIColor systemBackgroundColor]; +#endif if (self->_configuration.customizeRootView != nil) { self->_configuration.customizeRootView(surfaceHostingProxyRootView); } @@ -197,7 +201,11 @@ - (UIView *)createRootViewWithBridge:(RCTBridge *)bridge BOOL enableFabric = self->_configuration.fabricEnabled; UIView *rootView = RCTAppSetupDefaultRootView(bridge, moduleName, initProps, enableFabric); +#if TARGET_OS_VISION + rootView.backgroundColor = [UIColor clearColor]; +#else rootView.backgroundColor = [UIColor systemBackgroundColor]; +#endif return rootView; } diff --git a/packages/react-native/Libraries/LinkingIOS/RCTLinkingManager.h b/packages/react-native/Libraries/LinkingIOS/RCTLinkingManager.h index eff3b0c5461422..8bfee5fa745420 100644 --- a/packages/react-native/Libraries/LinkingIOS/RCTLinkingManager.h +++ b/packages/react-native/Libraries/LinkingIOS/RCTLinkingManager.h @@ -24,4 +24,6 @@ continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray> *_Nullable))restorationHandler; ++ (void)onOpenURL:(nonnull NSURL *)url NS_SWIFT_NAME(onOpenURL(url:)); + @end diff --git a/packages/react-native/Libraries/LinkingIOS/RCTLinkingManager.mm b/packages/react-native/Libraries/LinkingIOS/RCTLinkingManager.mm index 3fa06c43979bfd..b63c6340640452 100644 --- a/packages/react-native/Libraries/LinkingIOS/RCTLinkingManager.mm +++ b/packages/react-native/Libraries/LinkingIOS/RCTLinkingManager.mm @@ -15,6 +15,7 @@ #import "RCTLinkingPlugins.h" static NSString *const kOpenURLNotification = @"RCTOpenURLNotification"; +static NSURL *initialURL = nil; static void postNotificationWithURL(NSURL *URL, id sender) { @@ -81,6 +82,16 @@ + (BOOL)application:(UIApplication *)application return YES; } + ++ (void)onOpenURL:(NSURL *)url +{ + if (initialURL == nil) { + initialURL = url; + } else { + postNotificationWithURL(url, self); + } +} + - (void)handleOpenURLNotification:(NSNotification *)notification { [self sendEventWithName:@"url" body:notification.userInfo]; @@ -153,6 +164,7 @@ - (void)handleOpenURLNotification:(NSNotification *)notification RCT_EXPORT_METHOD(getInitialURL : (RCTPromiseResolveBlock)resolve reject : (__unused RCTPromiseRejectBlock)reject) { +#if !TARGET_OS_VISION NSURL *initialURL = nil; if (self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey]) { initialURL = self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey]; @@ -163,6 +175,8 @@ - (void)handleOpenURLNotification:(NSNotification *)notification initialURL = ((NSUserActivity *)userActivityDictionary[@"UIApplicationLaunchOptionsUserActivityKey"]).webpageURL; } } +#endif + // React Native visionOS uses static property to retrieve initialURL. resolve(RCTNullIfNil(initialURL.absoluteString)); } diff --git a/packages/react-native/Libraries/LinkingIOS/React-RCTLinking.podspec b/packages/react-native/Libraries/LinkingIOS/React-RCTLinking.podspec index 61d253eb3a4557..2988120a1741f4 100644 --- a/packages/react-native/Libraries/LinkingIOS/React-RCTLinking.podspec +++ b/packages/react-native/Libraries/LinkingIOS/React-RCTLinking.podspec @@ -46,8 +46,6 @@ Pod::Spec.new do |s| } s.framework = "UIKit" - s.framework = "UIKit" - s.dependency "React-Core/RCTLinkingHeaders", version s.dependency "ReactCommon/turbomodule/core", version s.dependency "React-jsi", version diff --git a/packages/react-native/Libraries/NativeAnimation/React-RCTAnimation.podspec b/packages/react-native/Libraries/NativeAnimation/React-RCTAnimation.podspec index d582e13b22924e..8a10d02f1fe8b0 100644 --- a/packages/react-native/Libraries/NativeAnimation/React-RCTAnimation.podspec +++ b/packages/react-native/Libraries/NativeAnimation/React-RCTAnimation.podspec @@ -45,8 +45,6 @@ Pod::Spec.new do |s| } s.framework = ["UIKit", "QuartzCore"] - s.framework = ["UIKit", "QuartzCore"] - s.dependency "RCT-Folly", folly_version s.dependency "RCTTypeSafety" s.dependency "React-jsi" diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTMainWindow.swift b/packages/react-native/Libraries/SwiftExtensions/RCTMainWindow.swift index 1bf0bca5901b63..85652c59463708 100644 --- a/packages/react-native/Libraries/SwiftExtensions/RCTMainWindow.swift +++ b/packages/react-native/Libraries/SwiftExtensions/RCTMainWindow.swift @@ -15,20 +15,121 @@ import SwiftUI } ``` - Note: If you want to create additional windows in your app, create a new `WindowGroup {}` and pass it a `RCTRootViewRepresentable`. -*/ + Note: If you want to create additional windows in your app, use `RCTWindow()`. + */ public struct RCTMainWindow: Scene { var moduleName: String var initialProps: RCTRootViewRepresentable.InitialPropsType + var onOpenURLCallback: ((URL) -> ())? + var devMenuSceneAnchor: UnitPoint? + var contentView: AnyView? - public init(moduleName: String, initialProps: RCTRootViewRepresentable.InitialPropsType = nil) { + var rootView: RCTRootViewRepresentable { + RCTRootViewRepresentable(moduleName: moduleName, initialProps: initialProps, devMenuSceneAnchor: devMenuSceneAnchor) + } + + /// Creates new RCTMainWindowWindow. + /// + /// - Parameters: + /// - moduleName: Name of the module registered using `AppRegistry.registerComponent()` + /// - initialProps: Initial properties for this view. + /// - devMenuPlacement: Placement of the additional controls for triggering reload command and dev menu trigger. + public init( + moduleName: String, + initialProps: RCTRootViewRepresentable.InitialPropsType = nil, + devMenuSceneAnchor: UnitPoint? = .bottom + ) { self.moduleName = moduleName self.initialProps = initialProps + self.devMenuSceneAnchor = devMenuSceneAnchor + self.contentView = AnyView(rootView) + } + + /// Creates new RCTMainWindowWindow. + /// + /// - Parameters: + /// - moduleName: Name of the module registered using `AppRegistry.registerComponent()` + /// - initialProps: Initial properties for this view. + /// - devMenuPlacement: Placement of the additional controls for triggering reload command and dev menu trigger. + /// - contentView: Closure which accepts rootView, allows to apply additional modifiers to React Native rootView. + public init( + moduleName: String, + initialProps: RCTRootViewRepresentable.InitialPropsType = nil, + devMenuSceneAnchor: UnitPoint? = .bottom, + @ViewBuilder contentView: @escaping (_ view: RCTRootViewRepresentable) -> Content + ) { + self.moduleName = moduleName + self.initialProps = initialProps + self.devMenuSceneAnchor = devMenuSceneAnchor + self.contentView = AnyView(contentView(rootView)) } public var body: some Scene { WindowGroup { - RCTRootViewRepresentable(moduleName: moduleName, initialProps: initialProps) + contentView + .modifier(WindowHandlingModifier()) + .onOpenURL(perform: { url in + onOpenURLCallback?(url) + }) + } + } +} + +extension RCTMainWindow { + public func onOpenURL(perform action: @escaping (URL) -> ()) -> Self { + var scene = self + scene.onOpenURLCallback = action + return scene + } +} + +/** + Handles data sharing between React Native and SwiftUI views. + */ +public struct WindowHandlingModifier: ViewModifier { + typealias UserInfoType = Dictionary + + @Environment(\.reactContext) private var reactContext + @Environment(\.openWindow) private var openWindow + @Environment(\.dismissWindow) private var dismissWindow + @Environment(\.supportsMultipleWindows) private var supportsMultipleWindows + + public init() {} + + public func body(content: Content) -> some View { + // Attach listeners only if app supports multiple windows + if supportsMultipleWindows { + content + .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("RCTOpenWindow"))) { data in + guard let id = data.userInfo?["id"] as? String else { return } + reactContext.scenes.updateValue(RCTSceneData(id: id, props: data.userInfo?["userInfo"] as? UserInfoType), forKey: id) + openWindow(id: id) + } + .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("RCTUpdateWindow"))) { data in + guard + let id = data.userInfo?["id"] as? String, + let userInfo = data.userInfo?["userInfo"] as? UserInfoType else { return } + reactContext.scenes[id]?.props = userInfo + } + .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("RCTDismissWindow"))) { data in + guard let id = data.userInfo?["id"] as? String else { return } + dismissWindow(id: id) + reactContext.scenes.removeValue(forKey: id) + } + .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("RCTOpenImmersiveSpace"))) { data in + guard let id = data.userInfo?["id"] as? String else { return } + reactContext.scenes.updateValue( + RCTSceneData(id: id, props: data.userInfo?["userInfo"] as? UserInfoType), + forKey: id + ) + } + .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("RCTDismissImmersiveSpace"))) { data in + guard let id = data.userInfo?["id"] as? String else { return } + reactContext.scenes.removeValue(forKey: id) + } + } else { + content } } } + diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTReactContext.swift b/packages/react-native/Libraries/SwiftExtensions/RCTReactContext.swift new file mode 100644 index 00000000000000..4f5c3b3738b0e7 --- /dev/null +++ b/packages/react-native/Libraries/SwiftExtensions/RCTReactContext.swift @@ -0,0 +1,45 @@ +import SwiftUI +import Observation + +@Observable +public class RCTSceneData: Identifiable { + public var id: String + public var props: Dictionary? + + init(id: String, props: Dictionary?) { + self.id = id + self.props = props + } +} + +extension RCTSceneData: Equatable { + public static func == (lhs: RCTSceneData, rhs: RCTSceneData) -> Bool { + lhs.id == rhs.id && NSDictionary(dictionary: lhs.props ?? [:]).isEqual(to: rhs.props ?? [:]) + } +} + +@Observable +public class RCTReactContext { + public var scenes: Dictionary = [:] + + public func getSceneData(id: String) -> RCTSceneData? { + return scenes[id] + } +} + +extension RCTReactContext: Equatable { + public static func == (lhs: RCTReactContext, rhs: RCTReactContext) -> Bool { + NSDictionary(dictionary: lhs.scenes).isEqual(to: rhs.scenes) + } +} + +public extension EnvironmentValues { + var reactContext: RCTReactContext { + get { self[RCTSceneContextKey.self] } + set { self[RCTSceneContextKey.self] = newValue } + } +} + +private struct RCTSceneContextKey: EnvironmentKey { + static var defaultValue: RCTReactContext = RCTReactContext() +} diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTReactViewController.h b/packages/react-native/Libraries/SwiftExtensions/RCTReactViewController.h index 13de19c37cf0e2..aa77150ce21c92 100644 --- a/packages/react-native/Libraries/SwiftExtensions/RCTReactViewController.h +++ b/packages/react-native/Libraries/SwiftExtensions/RCTReactViewController.h @@ -13,4 +13,6 @@ - (instancetype _Nonnull)initWithModuleName:(NSString *_Nonnull)moduleName initProps:(NSDictionary *_Nullable)initProps; +-(void)updateProps:(NSDictionary *_Nullable)newProps; + @end diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTReactViewController.m b/packages/react-native/Libraries/SwiftExtensions/RCTReactViewController.m index e051b6a1aabe48..5783b1bcadbc65 100644 --- a/packages/react-native/Libraries/SwiftExtensions/RCTReactViewController.m +++ b/packages/react-native/Libraries/SwiftExtensions/RCTReactViewController.m @@ -64,8 +64,12 @@ - (void)updateProps:(NSDictionary *)newProps { return; } + + if (newProps != nil && ![rootView.appProperties isEqualToDictionary:newProps]) { - [rootView setAppProperties:newProps]; + NSMutableDictionary *newProperties = [rootView.appProperties mutableCopy]; + [newProperties setValuesForKeysWithDictionary:newProps]; + [rootView setAppProperties:newProperties]; } } @end diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTRootViewRepresentable.swift b/packages/react-native/Libraries/SwiftExtensions/RCTRootViewRepresentable.swift index 6a89db9d08e2d7..cb774b8327ca9b 100644 --- a/packages/react-native/Libraries/SwiftExtensions/RCTRootViewRepresentable.swift +++ b/packages/react-native/Libraries/SwiftExtensions/RCTRootViewRepresentable.swift @@ -1,4 +1,5 @@ import SwiftUI +import React /** SwiftUI view enclosing `RCTReactViewController`. Its main purpose is to display React Native views inside of SwiftUI lifecycle. @@ -16,17 +17,57 @@ public struct RCTRootViewRepresentable: UIViewControllerRepresentable { var moduleName: String var initialProps: InitialPropsType + var devMenuSceneAnchor: UnitPoint? - public init(moduleName: String, initialProps: InitialPropsType = nil) { + public init( + moduleName: String, + initialProps: InitialPropsType = nil, + devMenuSceneAnchor: UnitPoint? = .bottom + ) { self.moduleName = moduleName self.initialProps = initialProps + self.devMenuSceneAnchor = devMenuSceneAnchor } - public func makeUIViewController(context: Context) -> UIViewController { - RCTReactViewController(moduleName: moduleName, initProps: initialProps) + public func makeUIViewController(context: Context) -> RCTReactViewController { + let viewController = RCTReactViewController(moduleName: moduleName, initProps: initialProps) +#if DEBUG + if let devMenuSceneAnchor { + let ornament = UIHostingOrnament(sceneAnchor: devMenuSceneAnchor) { + DevMenuView() + } + viewController.ornaments.append(ornament) + } +#endif + return viewController } - public func updateUIViewController(_ uiViewController: UIViewController, context: Context) { - // noop + public func updateUIViewController(_ uiViewController: RCTReactViewController, context: Context) { + uiViewController.updateProps(initialProps) + } +} + +/** + Toolbar which displays additional controls to easily open dev menu and trigger reload command. + */ +struct DevMenuView: View { + var body: some View { + HStack { + Button(action: { + RCTTriggerReloadCommandListeners("User Reload") + }, label: { + Image(systemName: "arrow.clockwise") + }) + Button(action: { + NotificationCenter.default.post( + Notification(name: Notification.Name("RCTShowDevMenuNotification"), object: nil) + ) + }, + label: { + Image(systemName: "filemenu.and.selection") + }) + } + .padding() + .glassBackgroundEffect() } } diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTWindow.swift b/packages/react-native/Libraries/SwiftExtensions/RCTWindow.swift new file mode 100644 index 00000000000000..d2bc884953b57a --- /dev/null +++ b/packages/react-native/Libraries/SwiftExtensions/RCTWindow.swift @@ -0,0 +1,97 @@ +import SwiftUI +import React + +/** + `RCTWindow` is a SwiftUI struct that returns additional scenes. + + Example usage: + ``` + RCTWindow(id: "SecondWindow", sceneData: reactContext.getSceneData(id: "SecondWindow")) + ``` + */ +public struct RCTWindow : Scene { + var id: String + var sceneData: RCTSceneData? + var moduleName: String + var contentView: AnyView? + + func getRootView(sceneData: RCTSceneData?) -> RCTRootViewRepresentable { + return RCTRootViewRepresentable(moduleName: moduleName, initialProps: sceneData?.props ?? [:], devMenuSceneAnchor: nil) + } + + public var body: some Scene { + WindowGroup(id: id) { + Group { + contentView + } + .onAppear { + if sceneData == nil { + RCTFatal(RCTErrorWithMessage("Passed scene data is nil, make sure to pass sceneContext to RCTWindow() in App.swift")) + } + } + } + } +} + +extension RCTWindow { + /// Creates new RCTWindow. + /// + /// - Parameters: + /// - id: Unique identifier of the window. + /// - moduleName: Name of the module registered using `AppRegistry.registerComponent()` + /// - sceneData: Data of the scene. Used to sync JS state between windows. + public init(id: String, moduleName: String, sceneData: RCTSceneData?) { + self.id = id + self.moduleName = moduleName + self.sceneData = sceneData + self.contentView = AnyView(getRootView(sceneData: sceneData)) + } + + /// Creates new RCTWindow with additional closure to allow applying modifiers to rootView. + /// + /// - Parameters: + /// - id: Unique identifier of the window. + /// - moduleName: Name of the module registered using `AppRegistry.registerComponent()` + /// - sceneData: Data of the scene. Used to sync JS state between windows. + /// - contentView: Closure which accepts rootView, allows to apply additional modifiers to React Native rootView. + public init( + id: String, + moduleName: String, + sceneData: RCTSceneData?, + @ViewBuilder contentView: @escaping (_ view: RCTRootViewRepresentable) -> Content + ) { + self.id = id + self.moduleName = moduleName + self.sceneData = sceneData + self.contentView = AnyView(contentView(getRootView(sceneData: sceneData))) + } + + /// Creates new RCTWindow with additional closure to allow applying modifiers to rootView. + /// + /// - Parameters: + /// - id: Unique identifier of the window. Same id will be used for moduleName. + /// - sceneData: Data of the scene. Used to sync JS state between windows. + /// - contentView: Closure which accepts rootView, allows to apply additional modifiers to React Native rootView. + public init( + id: String, + sceneData: RCTSceneData?, + @ViewBuilder contentView: @escaping (_ view: RCTRootViewRepresentable) -> Content + ) { + self.id = id + self.moduleName = id + self.sceneData = sceneData + self.contentView = AnyView(contentView(getRootView(sceneData: sceneData))) + } + + /// Creates new RCTWindow. + /// + /// - Parameters: + /// - id: Unique identifier of the window. Same id will be used for moduleName. + /// - sceneData: Data of the scene. Used to sync JS state between windows. + public init(id: String, sceneData: RCTSceneData?) { + self.id = id + self.moduleName = id + self.sceneData = sceneData + self.contentView = AnyView(getRootView(sceneData: sceneData)) + } +} diff --git a/packages/react-native/Libraries/SwiftExtensions/React-RCTSwiftExtensions.podspec b/packages/react-native/Libraries/SwiftExtensions/React-RCTSwiftExtensions.podspec index 531f1d8172ca7d..9d61b8e4cf31c3 100644 --- a/packages/react-native/Libraries/SwiftExtensions/React-RCTSwiftExtensions.podspec +++ b/packages/react-native/Libraries/SwiftExtensions/React-RCTSwiftExtensions.podspec @@ -25,4 +25,5 @@ Pod::Spec.new do |s| s.dependency "React-Core" s.dependency "React-RCTXR" + s.dependency "React-RCTWindowManager" end diff --git a/packages/react-native/Libraries/WindowManager/NativeWindowManager.js b/packages/react-native/Libraries/WindowManager/NativeWindowManager.js new file mode 100644 index 00000000000000..2f9c0bc834de7d --- /dev/null +++ b/packages/react-native/Libraries/WindowManager/NativeWindowManager.js @@ -0,0 +1,8 @@ +/** + * @flow strict + * @format + */ + +export * from '../../visionos_modules/NativeWindowManager'; +import NativeWindowManager from '../../visionos_modules/NativeWindowManager'; +export default NativeWindowManager; diff --git a/packages/react-native/Libraries/WindowManager/RCTWindowManager.h b/packages/react-native/Libraries/WindowManager/RCTWindowManager.h new file mode 100644 index 00000000000000..8d782b1bfe77e7 --- /dev/null +++ b/packages/react-native/Libraries/WindowManager/RCTWindowManager.h @@ -0,0 +1,6 @@ +#import +#import + +@interface RCTWindowManager : NSObject + +@end diff --git a/packages/react-native/Libraries/WindowManager/RCTWindowManager.mm b/packages/react-native/Libraries/WindowManager/RCTWindowManager.mm new file mode 100644 index 00000000000000..3700bceba20b95 --- /dev/null +++ b/packages/react-native/Libraries/WindowManager/RCTWindowManager.mm @@ -0,0 +1,90 @@ +#import + +#import + +#import +#import +#import + +// Events +static NSString *const RCTOpenWindow = @"RCTOpenWindow"; +static NSString *const RCTDismissWindow = @"RCTDismissWindow"; +static NSString *const RCTUpdateWindow = @"RCTUpdateWindow"; + +@interface RCTWindowManager () +@end + +@implementation RCTWindowManager + +RCT_EXPORT_MODULE(WindowManager) + +RCT_EXPORT_METHOD(openWindow + : (NSString *)windowId userInfo + : (NSDictionary *)userInfo resolve + : (RCTPromiseResolveBlock)resolve reject + : (RCTPromiseRejectBlock)reject) +{ + RCTExecuteOnMainQueue(^{ + if (!RCTSharedApplication().supportsMultipleScenes) { + reject(@"ERROR", @"Multiple scenes not supported", nil); + } + NSMutableDictionary *userInfoDict = [[NSMutableDictionary alloc] init]; + [userInfoDict setValue:windowId forKey:@"id"]; + if (userInfo != nil) { + [userInfoDict setValue:userInfo forKey:@"userInfo"]; + } + [[NSNotificationCenter defaultCenter] postNotificationName:RCTOpenWindow object:self userInfo:userInfoDict]; + resolve(nil); + }); +} + +RCT_EXPORT_METHOD(closeWindow + : (NSString *)windowId resolve + : (RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) +{ + RCTExecuteOnMainQueue(^{ + [[NSNotificationCenter defaultCenter] postNotificationName:RCTDismissWindow object:self userInfo:@{@"id": windowId}]; + resolve(nil); + }); +} + +RCT_EXPORT_METHOD(updateWindow + : (NSString *)windowId userInfo + : (NSDictionary *)userInfo resolve + : (RCTPromiseResolveBlock)resolve reject + : (RCTPromiseRejectBlock)reject) +{ + RCTExecuteOnMainQueue(^{ + if (!RCTSharedApplication().supportsMultipleScenes) { + reject(@"ERROR", @"Multiple scenes not supported", nil); + } + NSMutableDictionary *userInfoDict = [[NSMutableDictionary alloc] init]; + [userInfoDict setValue:windowId forKey:@"id"]; + if (userInfo != nil) { + [userInfoDict setValue:userInfo forKey:@"userInfo"]; + } + [[NSNotificationCenter defaultCenter] postNotificationName:RCTUpdateWindow object:self userInfo:userInfoDict]; + resolve(nil); + }); +} + +- (facebook::react::ModuleConstants)constantsToExport { + return [self getConstants]; +} + +- (facebook::react::ModuleConstants)getConstants { + __block facebook::react::ModuleConstants constants; + RCTUnsafeExecuteOnMainQueueSync(^{ + constants = facebook::react::typedConstants({ + .supportsMultipleScenes = RCTSharedApplication().supportsMultipleScenes + }); + }); + + return constants; +} + +- (std::shared_ptr)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params { + return std::make_shared(params); +} + +@end diff --git a/packages/react-native/Libraries/WindowManager/WindowManager.d.ts b/packages/react-native/Libraries/WindowManager/WindowManager.d.ts new file mode 100644 index 00000000000000..bcdf96c272c21c --- /dev/null +++ b/packages/react-native/Libraries/WindowManager/WindowManager.d.ts @@ -0,0 +1,16 @@ +export interface WindowStatic { + id: String; + open (props?: Object): Promise; + update (props: Object): Promise; + close (): Promise; +} + +export interface WindowManagerStatic { + getWindow(id: String): Window; + supportsMultipleScenes: boolean; +} + +export const WindowManager: WindowManagerStatic; +export type WindowManager = WindowManagerStatic; +export const Window: WindowStatic; +export type Window = WindowStatic; diff --git a/packages/react-native/Libraries/WindowManager/WindowManager.js b/packages/react-native/Libraries/WindowManager/WindowManager.js new file mode 100644 index 00000000000000..bb39535a65bb1a --- /dev/null +++ b/packages/react-native/Libraries/WindowManager/WindowManager.js @@ -0,0 +1,63 @@ +/** + * @format + * @flow strict + * @jsdoc + */ + +import NativeWindowManager from './NativeWindowManager'; + +const WindowManager = { + getWindow: function (id: string): Window { + return new Window(id); + }, + + // $FlowIgnore[unsafe-getters-setters] + get supportsMultipleScenes(): boolean { + if (NativeWindowManager == null) { + return false; + } + + const nativeConstants = NativeWindowManager.getConstants(); + return nativeConstants.supportsMultipleScenes || false; + }, +}; + +class Window { + id: string; + + constructor(id: string) { + this.id = id; + } + + // $FlowIgnore[unclear-type] + open(props: ?Object): Promise { + if (NativeWindowManager != null && NativeWindowManager.openWindow != null) { + return NativeWindowManager.openWindow(this.id, props); + } + return Promise.reject(new Error('NativeWindowManager is not available')); + } + + // $FlowIgnore[unclear-type] + close(): Promise { + if ( + NativeWindowManager != null && + NativeWindowManager.closeWindow != null + ) { + return NativeWindowManager.closeWindow(this.id); + } + return Promise.reject(new Error('NativeWindowManager is not available')); + } + + // $FlowIgnore[unclear-type] + update(props: ?Object): Promise { + if ( + NativeWindowManager != null && + NativeWindowManager.updateWindow != null + ) { + return NativeWindowManager.updateWindow(this.id, props); + } + return Promise.reject(new Error('NativeWindowManager is not available')); + } +} + +module.exports = WindowManager; diff --git a/packages/react-native/Libraries/XR/ImmersiveBridge.swift b/packages/react-native/Libraries/XR/ImmersiveBridge.swift index 45fdbcf4087b00..43bdfe5b170739 100644 --- a/packages/react-native/Libraries/XR/ImmersiveBridge.swift +++ b/packages/react-native/Libraries/XR/ImmersiveBridge.swift @@ -9,6 +9,7 @@ import SwiftUI public typealias CompletionHandlerType = (_ result: ImmersiveSpaceResult) -> Void +#if os(visionOS) /** * Utility view used to bridge the gap between SwiftUI environment and UIKit. * @@ -44,12 +45,17 @@ struct ImmersiveBridgeView: View { } } } +#endif -@objc public class ImmersiveBridgeFactory: NSObject { +@objc public class SwiftUIBridgeFactory: NSObject { @objc public static func makeImmersiveBridgeView( spaceId: String, completionHandler: @escaping CompletionHandlerType ) -> UIViewController { +#if os(visionOS) return UIHostingController(rootView: ImmersiveBridgeView(spaceId: spaceId, completionHandler: completionHandler)) +#else + return UIViewController() +#endif } } diff --git a/packages/react-native/Libraries/XR/NativeXRModule.js b/packages/react-native/Libraries/XR/NativeXRModule.js index c34b296bc3e4a5..36320028acbaab 100644 --- a/packages/react-native/Libraries/XR/NativeXRModule.js +++ b/packages/react-native/Libraries/XR/NativeXRModule.js @@ -3,6 +3,6 @@ * @format */ -export * from '../../src/private/specs/visionos_modules/NativeXRModule'; -import NativeXRModule from '../../src/private/specs/visionos_modules/NativeXRModule'; +export * from '../../visionos_modules/NativeXRModule'; +import NativeXRModule from '../../visionos_modules/NativeXRModule'; export default NativeXRModule; diff --git a/packages/react-native/Libraries/XR/RCTXRModule.mm b/packages/react-native/Libraries/XR/RCTXRModule.mm index 8b5db6c7cbd008..f0c600b3a09c99 100644 --- a/packages/react-native/Libraries/XR/RCTXRModule.mm +++ b/packages/react-native/Libraries/XR/RCTXRModule.mm @@ -7,11 +7,16 @@ #import #import "RCTXR-Swift.h" +// Events +static NSString *const RCTOpenImmersiveSpace = @"RCTOpenImmersiveSpace"; +static NSString *const RCTDismissImmersiveSpace = @"RCTDismissImmersiveSpace"; + @interface RCTXRModule () @end @implementation RCTXRModule { UIViewController *_immersiveBridgeView; + NSString *_currentSessionId; } RCT_EXPORT_MODULE() @@ -20,28 +25,51 @@ @implementation RCTXRModule { : (RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject) { - [self removeImmersiveBridge]; + [self removeViewController:self->_immersiveBridgeView]; + self->_immersiveBridgeView = nil; + RCTExecuteOnMainQueue(^{ + if (self->_currentSessionId != nil) { + [[NSNotificationCenter defaultCenter] postNotificationName:RCTDismissImmersiveSpace object:self userInfo:@{@"id": self->_currentSessionId}]; + } + }); + _currentSessionId = nil; resolve(nil); } RCT_EXPORT_METHOD(requestSession - : (NSString *)sessionId resolve - : (RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) + : (NSString *)sessionId userInfo + : (NSDictionary *)userInfo resolve + : (RCTPromiseResolveBlock)resolve reject + : (RCTPromiseRejectBlock)reject) { RCTExecuteOnMainQueue(^{ + if (!RCTSharedApplication().supportsMultipleScenes) { + reject(@"ERROR", @"Multiple scenes not supported", nil); + } UIWindow *keyWindow = RCTKeyWindow(); UIViewController *rootViewController = keyWindow.rootViewController; if (self->_immersiveBridgeView == nil) { - self->_immersiveBridgeView = [ImmersiveBridgeFactory makeImmersiveBridgeViewWithSpaceId:sessionId + NSMutableDictionary *userInfoDict = [[NSMutableDictionary alloc] init]; + [userInfoDict setValue:sessionId forKey:@"id"]; + if (userInfo != nil) { + [userInfoDict setValue:userInfo forKey:@"userInfo"]; + } + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + [notificationCenter postNotificationName:RCTOpenImmersiveSpace object:self userInfo:userInfoDict]; + self->_currentSessionId = sessionId; + + self->_immersiveBridgeView = [SwiftUIBridgeFactory makeImmersiveBridgeViewWithSpaceId:sessionId completionHandler:^(enum ImmersiveSpaceResult result){ if (result == ImmersiveSpaceResultError) { reject(@"ERROR", @"Immersive Space failed to open, the system cannot fulfill the request.", nil); - [self removeImmersiveBridge]; + [self removeViewController:self->_immersiveBridgeView]; + self->_immersiveBridgeView = nil; } else if (result == ImmersiveSpaceResultUserCancelled) { reject(@"ERROR", @"Immersive Space canceled by user", nil); - [self removeImmersiveBridge]; + [self removeViewController:self->_immersiveBridgeView]; + self->_immersiveBridgeView = nil; } else if (result == ImmersiveSpaceResultOpened) { resolve(nil); } @@ -56,28 +84,13 @@ @implementation RCTXRModule { }); } -- (facebook::react::ModuleConstants)constantsToExport { - return [self getConstants]; -} - -- (facebook::react::ModuleConstants)getConstants { - __block facebook::react::ModuleConstants constants; - RCTUnsafeExecuteOnMainQueueSync(^{ - constants = facebook::react::typedConstants({ - .supportsMultipleScenes = RCTSharedApplication().supportsMultipleScenes - }); - }); - - return constants; -} -- (void) removeImmersiveBridge +- (void)removeViewController:(UIViewController*)viewController { RCTExecuteOnMainQueue(^{ - [self->_immersiveBridgeView willMoveToParentViewController:nil]; - [self->_immersiveBridgeView.view removeFromSuperview]; - [self->_immersiveBridgeView removeFromParentViewController]; - self->_immersiveBridgeView = nil; + [viewController willMoveToParentViewController:nil]; + [viewController.view removeFromSuperview]; + [viewController removeFromParentViewController]; }); } diff --git a/packages/react-native/Libraries/XR/XR.d.ts b/packages/react-native/Libraries/XR/XR.d.ts index 11d397a4ebde34..293a97bb084c3e 100644 --- a/packages/react-native/Libraries/XR/XR.d.ts +++ b/packages/react-native/Libraries/XR/XR.d.ts @@ -1,8 +1,7 @@ export interface XRStatic { - requestSession(sessionId: string): Promise; + requestSession(sessionId: string, userInfo: Object): Promise; endSession(): Promise; - supportsMultipleScenes: boolean; } export const XR: XRStatic; diff --git a/packages/react-native/Libraries/XR/XR.js b/packages/react-native/Libraries/XR/XR.js index 3487429aff1bb5..923a3184c71dea 100644 --- a/packages/react-native/Libraries/XR/XR.js +++ b/packages/react-native/Libraries/XR/XR.js @@ -7,9 +7,10 @@ import NativeXRModule from './NativeXRModule'; const XR = { - requestSession: (sessionId?: string): Promise => { + // $FlowIgnore[unclear-type] + requestSession: (sessionId: string, userInfo: ?Object): Promise => { if (NativeXRModule != null && NativeXRModule.requestSession != null) { - return NativeXRModule.requestSession(sessionId); + return NativeXRModule.requestSession(sessionId, userInfo); } return Promise.reject(new Error('NativeXRModule is not available')); }, @@ -19,15 +20,6 @@ const XR = { } return Promise.reject(new Error('NativeXRModule is not available')); }, - // $FlowIgnore[unsafe-getters-setters] - get supportsMultipleScenes(): boolean { - if (NativeXRModule == null) { - return false; - } - - const nativeConstants = NativeXRModule.getConstants(); - return nativeConstants.supportsMultipleScenes || false; - }, }; module.exports = XR; diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index cfb667fa41c3a7..0e652f42d8ac74 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -9716,6 +9716,28 @@ exports[`public API should not change unintentionally Libraries/WebSocket/WebSoc exports[`public API should not change unintentionally Libraries/WebSocket/WebSocketInterceptor.js 1`] = `"UNTYPED MODULE"`; +exports[`public API should not change unintentionally Libraries/WindowManager/NativeWindowManager.js 1`] = ` +"export * from \\"../../src/private/specs/visionos_modules/NativeWindowManager\\"; +declare export default typeof NativeWindowManager; +" +`; + +exports[`public API should not change unintentionally Libraries/WindowManager/WindowManager.js 1`] = ` +"declare const WindowManager: { + getWindow: (id: string) => Window, + get supportsMultipleScenes(): boolean, +}; +declare class Window { + id: string; + constructor(id: string): void; + open(props: ?Object): Promise; + close(): Promise; + update(props: ?Object): Promise; +} +declare module.exports: WindowManager; +" +`; + exports[`public API should not change unintentionally Libraries/XR/NativeXRModule.js 1`] = ` "export * from \\"../../src/private/specs/visionos_modules/NativeXRModule\\"; declare export default typeof NativeXRModule; @@ -9724,9 +9746,8 @@ declare export default typeof NativeXRModule; exports[`public API should not change unintentionally Libraries/XR/XR.js 1`] = ` "declare const XR: { - requestSession: (sessionId?: string) => Promise, + requestSession: (sessionId: string, userInfo: ?Object) => Promise, endSession: () => Promise, - get supportsMultipleScenes(): boolean, }; declare module.exports: XR; " @@ -9851,6 +9872,7 @@ declare module.exports: { get Settings(): Settings, get Share(): Share, get XR(): XR, + get WindowManager(): WindowManager, get StyleSheet(): StyleSheet, get Systrace(): Systrace, get ToastAndroid(): ToastAndroid, diff --git a/packages/react-native/React-Core.podspec b/packages/react-native/React-Core.podspec index 5b00320d9a570c..3a37faece69404 100644 --- a/packages/react-native/React-Core.podspec +++ b/packages/react-native/React-Core.podspec @@ -41,6 +41,7 @@ header_subspecs = { 'RCTTextHeaders' => 'Libraries/Text/**/*.h', 'RCTVibrationHeaders' => 'Libraries/Vibration/*.h', 'RCTXRHeaders' => 'Libraries/XR/*.h', + 'RCTWindowManagerHeaders' => 'Libraries/WindowManager/*.h', } frameworks_search_paths = [] diff --git a/packages/react-native/React.podspec b/packages/react-native/React.podspec index 2d085e63040906..50397b11182021 100644 --- a/packages/react-native/React.podspec +++ b/packages/react-native/React.podspec @@ -54,4 +54,5 @@ Pod::Spec.new do |s| s.dependency "React-RCTText", version s.dependency "React-RCTVibration", version s.dependency "React-RCTXR", version + s.dependency "React-RCTWindowManager", version end diff --git a/packages/react-native/React/Base/RCTUtils.m b/packages/react-native/React/Base/RCTUtils.m index 1573a675f23a6b..4e47006a52c4d9 100644 --- a/packages/react-native/React/Base/RCTUtils.m +++ b/packages/react-native/React/Base/RCTUtils.m @@ -566,7 +566,17 @@ BOOL RCTRunningInAppExtension(void) if (RCTRunningInAppExtension()) { return nil; } - + + id delegate = RCTSharedApplication().delegate; + + SEL lastFocusedWindowSelector = NSSelectorFromString(@"lastFocusedWindow"); + if ([delegate respondsToSelector:lastFocusedWindowSelector]) { + UIWindow *lastFocusedWindow = [delegate performSelector:lastFocusedWindowSelector]; + if (lastFocusedWindow) { + return lastFocusedWindow; + } + } + NSSet *connectedScenes = RCTSharedApplication().connectedScenes; UIScene *foregroundActiveScene; @@ -582,6 +592,7 @@ BOOL RCTRunningInAppExtension(void) if (scene.session.role == UISceneSessionRoleImmersiveSpaceApplication) { continue; } + #endif if (scene.activationState == UISceneActivationStateForegroundActive) { @@ -598,6 +609,24 @@ BOOL RCTRunningInAppExtension(void) UIScene *sceneToUse = foregroundActiveScene ? foregroundActiveScene : foregroundInactiveScene; UIWindowScene *windowScene = (UIWindowScene *)sceneToUse; +#if TARGET_OS_VISION + // Ornaments are supported only on visionOS. + // When clicking on an ornament it becomes the keyWindow. + // Presenting a RN modal from ornament leads to a crash. + UIWindow* keyWindow = windowScene.keyWindow; + BOOL isOrnament = [keyWindow.debugDescription containsString:@"Ornament"]; + if (isOrnament) { + for (UIWindow *window in windowScene.windows) { + BOOL isOrnament = [window.debugDescription containsString:@"Ornament"]; + if (window != keyWindow && !isOrnament) { + return window; + } + } + } + + return keyWindow; +#endif + if (@available(iOS 15.0, *)) { return windowScene.keyWindow; } diff --git a/packages/react-native/React/CoreModules/RCTDeviceInfo.mm b/packages/react-native/React/CoreModules/RCTDeviceInfo.mm index 7f9c3e2f80995f..454a3252cc5e1f 100644 --- a/packages/react-native/React/CoreModules/RCTDeviceInfo.mm +++ b/packages/react-native/React/CoreModules/RCTDeviceInfo.mm @@ -51,8 +51,6 @@ - (void)initialize selector:@selector(didReceiveNewContentSizeMultiplier) name:RCTAccessibilityManagerDidUpdateMultiplierNotification object:[_moduleRegistry moduleForName:"AccessibilityManager"]]; - -#if !TARGET_OS_VISION _currentInterfaceDimensions = [self _exportedDimensions]; @@ -106,12 +104,7 @@ - (void)_cleanupObservers [[NSNotificationCenter defaultCenter] removeObserver:self name:RCTAccessibilityManagerDidUpdateMultiplierNotification object:[_moduleRegistry moduleForName:"AccessibilityManager"]]; -#if !TARGET_OS_VISION - [[NSNotificationCenter defaultCenter] removeObserver:self - name:UIApplicationDidChangeStatusBarOrientationNotification - object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil]; -#endif + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:RCTUserInterfaceStyleDidChangeNotification object:nil]; @@ -128,8 +121,7 @@ - (void)_cleanupObservers static BOOL RCTIsIPhoneNotched() { static BOOL isIPhoneNotched = NO; -#if !TARGET_OS_VISION - static dispatch_once_t onceToken; + static dispatch_once_t onceToken; #if TARGET_OS_IOS dispatch_once(&onceToken, ^{ @@ -140,10 +132,6 @@ static BOOL RCTIsIPhoneNotched() }); #endif - // 20pt is the top safeArea value in non-notched devices - isIPhoneNotched = RCTSharedApplication().keyWindow.safeAreaInsets.top > 20; - }); -#endif return isIPhoneNotched; } diff --git a/packages/react-native/React/CoreModules/RCTKeyboardObserver.mm b/packages/react-native/React/CoreModules/RCTKeyboardObserver.mm index 0774d1f9a81ef7..ce483ddceb95fc 100644 --- a/packages/react-native/React/CoreModules/RCTKeyboardObserver.mm +++ b/packages/react-native/React/CoreModules/RCTKeyboardObserver.mm @@ -23,7 +23,6 @@ @implementation RCTKeyboardObserver - (void)startObserving { -#if !TARGET_OS_VISION NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; #define ADD_KEYBOARD_HANDLER(NAME, SELECTOR) [nc addObserver:self selector:@selector(SELECTOR:) name:NAME object:nil] @@ -36,7 +35,6 @@ - (void)startObserving ADD_KEYBOARD_HANDLER(UIKeyboardDidChangeFrameNotification, keyboardDidChangeFrame); #undef ADD_KEYBOARD_HANDLER -#endif } - (NSArray *)supportedEvents @@ -53,12 +51,9 @@ - (void)startObserving - (void)stopObserving { -#if !TARGET_OS_VISION [[NSNotificationCenter defaultCenter] removeObserver:self]; -#endif } -#if !TARGET_OS_VISION // Bridge might be already invalidated by the time the keyboard is about to be dismissed. // This might happen, for example, when reload from the packager is performed. // Thus we need to check against nil here. @@ -77,7 +72,6 @@ -(void)EVENT : (NSNotification *)notification IMPLEMENT_KEYBOARD_HANDLER(keyboardDidHide) IMPLEMENT_KEYBOARD_HANDLER(keyboardWillChangeFrame) IMPLEMENT_KEYBOARD_HANDLER(keyboardDidChangeFrame) -#endif - (std::shared_ptr)getTurboModule: (const facebook::react::ObjCTurboModule::InitParams &)params diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/Modal/RCTFabricModalHostViewController.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/Modal/RCTFabricModalHostViewController.mm index 4795d344bd189e..34c4025927be63 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/Modal/RCTFabricModalHostViewController.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/Modal/RCTFabricModalHostViewController.mm @@ -75,6 +75,9 @@ - (UIInterfaceOrientationMask)supportedInterfaceOrientations } return _supportedInterfaceOrientations; +#else + return UIInterfaceOrientationUnknown; +#endif } #endif // RCT_DEV diff --git a/packages/react-native/React/Views/RCTModalHostViewController.m b/packages/react-native/React/Views/RCTModalHostViewController.m index f8c8aef39499af..e99dde2cc4a6bf 100644 --- a/packages/react-native/React/Views/RCTModalHostViewController.m +++ b/packages/react-native/React/Views/RCTModalHostViewController.m @@ -68,6 +68,9 @@ - (UIInterfaceOrientationMask)supportedInterfaceOrientations } return _supportedInterfaceOrientations; +#else + return UIInterfaceOrientationUnknown; +#endif } #endif // RCT_DEV diff --git a/packages/react-native/React/Views/RCTWrapperViewController.m b/packages/react-native/React/Views/RCTWrapperViewController.m index 7b455799e1571a..eb041ad79a646e 100644 --- a/packages/react-native/React/Views/RCTWrapperViewController.m +++ b/packages/react-native/React/Views/RCTWrapperViewController.m @@ -29,9 +29,6 @@ - (instancetype)initWithContentView:(UIView *)contentView if ((self = [super initWithNibName:nil bundle:nil])) { _contentView = contentView; -#if !TARGET_OS_VISION - self.automaticallyAdjustsScrollViewInsets = NO; -#endif } return self; } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/localCommands.js b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/localCommands.js deleted file mode 100644 index dc87001156ac06..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/localCommands.js +++ /dev/null @@ -1,45 +0,0 @@ -const { - createBuild, - createLog, - createRun, - getRunOptions, - getLogOptions, - getBuildOptions, -} = require('@react-native-community/cli-platform-apple'); - -const platformName = 'visionos'; - -const run = { - name: 'run-visionos', - description: 'builds your app and starts it on visionOS simulator', - func: createRun({platformName}), - examples: [ - { - desc: 'Run on a specific simulator', - cmd: 'npx @callstack/react-native-visionos run-visionos --simulator "Apple Vision Pro"', - }, - ], - options: getRunOptions({platformName}), -}; - -const log = { - name: 'log-visionos', - description: 'starts visionOS device syslog tail', - func: createLog({platformName: 'visionos'}), - options: getLogOptions({platformName}), -}; - -const build = { - name: 'build-visionos', - description: 'builds your app for visionOS platform', - func: createBuild({platformName}), - examples: [ - { - desc: 'Build the app for all visionOS devices in Release mode', - cmd: 'npx @callstack/react-native-visionos build-visionos --mode "Release"', - }, - ], - options: getBuildOptions({platformName}), -}; - -module.exports = [run, log, build]; diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/React-graphics.podspec b/packages/react-native/ReactCommon/react/renderer/graphics/React-graphics.podspec index 9437d25206be86..1faeaf8581af65 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/React-graphics.podspec +++ b/packages/react-native/ReactCommon/react/renderer/graphics/React-graphics.podspec @@ -54,8 +54,6 @@ Pod::Spec.new do |s| s.header_mappings_dir = "../../.." header_search_paths = header_search_paths + ["\"$(PODS_TARGET_SRCROOT)/platform/ios\""] end - - s.framework = "UIKit" s.pod_target_xcconfig = { "USE_HEADERMAP" => "NO", "HEADER_SEARCH_PATHS" => header_search_paths.join(" "), diff --git a/packages/react-native/index.js b/packages/react-native/index.js index ed31324efdd00c..c28c033347acb6 100644 --- a/packages/react-native/index.js +++ b/packages/react-native/index.js @@ -92,6 +92,7 @@ import typeof Platform from './Libraries/Utilities/Platform'; import typeof useColorScheme from './Libraries/Utilities/useColorScheme'; import typeof useWindowDimensions from './Libraries/Utilities/useWindowDimensions'; import typeof Vibration from './Libraries/Vibration/Vibration'; +import typeof WindowManager from './Libraries/WindowManager/WindowManager'; import typeof XR from './Libraries/XR/XR'; import typeof YellowBox from './Libraries/YellowBox/YellowBoxDeprecated'; @@ -306,6 +307,9 @@ module.exports = { get XR(): XR { return require('./Libraries/XR/XR'); }, + get WindowManager(): WindowManager { + return require('./Libraries/WindowManager/WindowManager'); + }, get StyleSheet(): StyleSheet { return require('./Libraries/StyleSheet/StyleSheet'); }, diff --git a/packages/react-native/package.json b/packages/react-native/package.json index cf21ce07584d6a..69b3ae244ac604 100644 --- a/packages/react-native/package.json +++ b/packages/react-native/package.json @@ -91,7 +91,9 @@ "!template/package-lock.json", "!template/yarn.lock", "third-party-podspecs", - "types" + "types", + "visionos_modules", + "local-cli/localCommands.js" ], "scripts": { "prepack": "node ./scripts/prepack.js", @@ -161,7 +163,7 @@ "type": "modules", "ios": {}, "android": {}, - "jsSrcsDir": "src/private/specs/visionos_modules" + "jsSrcsDir": "visionos_modules" }, { "name": "rncore", diff --git a/packages/react-native/react-native.config.js b/packages/react-native/react-native.config.js index e880134104b1f8..a562950980ad08 100644 --- a/packages/react-native/react-native.config.js +++ b/packages/react-native/react-native.config.js @@ -97,9 +97,10 @@ const codegenCommand = { }; commands.push(codegenCommand); +commands.push(...localCommands); const config = { - commands: [bundleCommand, startCommand, codegenCommand, ...localCommands], + commands, platforms: { visionos: { npmPackageName: '@callstack/react-native-visionos', diff --git a/packages/react-native/scripts/react_native_pods.rb b/packages/react-native/scripts/react_native_pods.rb index dc24b1215c042e..84f0e1fceb4548 100644 --- a/packages/react-native/scripts/react_native_pods.rb +++ b/packages/react-native/scripts/react_native_pods.rb @@ -136,6 +136,7 @@ def use_react_native! ( pod 'RCTDeprecation', :path => "#{prefix}/ReactApple/Libraries/RCTFoundation/RCTDeprecation" pod 'React-RCTSwiftExtensions', :path => "#{prefix}/Libraries/SwiftExtensions" pod 'React-RCTXR', :path => "#{prefix}/Libraries/XR" + pod 'React-RCTWindowManager', :path => "#{prefix}/Libraries/WindowManager", :modular_headers => true if hermes_enabled setup_hermes!(:react_native_path => prefix) @@ -165,8 +166,6 @@ def use_react_native! ( pod 'fmt', :podspec => "#{prefix}/third-party-podspecs/fmt.podspec" pod 'RCT-Folly', :podspec => "#{prefix}/third-party-podspecs/RCT-Folly.podspec", :modular_headers => true pod 'fmt', :podspec => "#{prefix}/third-party-podspecs/fmt.podspec", :modular_headers => true - pod 'SocketRocket', :podspec => "#{prefix}/third-party-podspecs/SocketRocket.podspec", :modular_headers => true - folly_config = get_folly_config() run_codegen!( diff --git a/packages/react-native/sdks/hermes-engine/hermes-engine.podspec b/packages/react-native/sdks/hermes-engine/hermes-engine.podspec index aace5f0b5f99a1..34294219325e98 100644 --- a/packages/react-native/sdks/hermes-engine/hermes-engine.podspec +++ b/packages/react-native/sdks/hermes-engine/hermes-engine.podspec @@ -13,12 +13,13 @@ react_native_path = File.dirname(Pod::Executable.execute_command('node', ['-p', )', __dir__]).strip ) +puts "React Native path: #{react_native_path}" + # package.json package = JSON.parse(File.read(File.join(react_native_path, "package.json"))) version = package['version'] -# Temporaily build from source until visionOS supports prebuilt binaries -source_type = HermesEngineSourceType::BUILD_FROM_GITHUB_MAIN # hermes_source_type(version, react_native_path) +source_type = hermes_source_type(version, react_native_path) source = podspec_source(source_type, version, react_native_path) Pod::Spec.new do |spec| @@ -145,6 +146,7 @@ Pod::Spec.new do |spec| :name => '[RN] [2] Build Hermes', :input_files => ["#{hermesc_path}/ImportHermesc.cmake"], :output_files => [ + "${PODS_ROOT}/hermes-engine/build/iphonesimulator/API/hermes/hermes.framework/hermes", "${PODS_ROOT}/hermes-engine/build/xrsimulator/API/hermes/hermes.framework/hermes", ], :script => <<-EOS diff --git a/packages/react-native/sdks/hermes-engine/utils/build-hermes-xcode.sh b/packages/react-native/sdks/hermes-engine/utils/build-hermes-xcode.sh index b4e834875a18c3..0fa473e9c11fca 100755 --- a/packages/react-native/sdks/hermes-engine/utils/build-hermes-xcode.sh +++ b/packages/react-native/sdks/hermes-engine/utils/build-hermes-xcode.sh @@ -31,9 +31,6 @@ function get_deployment_target { elif [[ $1 == "xrsimulator" || $1 == "xros" ]]; then echo "${XROS_DEPLOYMENT_TARGET}" return - elif [[ $1 == "xrsimulator" || $1 == "xros" ]]; then - echo ${XROS_DEPLOYMENT_TARGET} - return fi echo "${IPHONEOS_DEPLOYMENT_TARGET}" diff --git a/packages/react-native/src/private/specs/visionos_modules/NativeXRModule.js b/packages/react-native/src/private/specs/visionos_modules/NativeXRModule.js deleted file mode 100644 index ce8d22dca68c49..00000000000000 --- a/packages/react-native/src/private/specs/visionos_modules/NativeXRModule.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * @flow strict - * @format - */ - -import type {TurboModule} from '../../../../Libraries/TurboModule/RCTExport'; - -import * as TurboModuleRegistry from '../../../../Libraries/TurboModule/TurboModuleRegistry'; - -export type XRModuleConstants = {| - +supportsMultipleScenes?: boolean, -|}; - -export interface Spec extends TurboModule { - +getConstants: () => XRModuleConstants; - - +requestSession: (sessionId?: string) => Promise; - +endSession: () => Promise; -} - -export default (TurboModuleRegistry.get('XRModule'): ?Spec); diff --git a/packages/react-native/template/App.tsx b/packages/react-native/template/App.tsx deleted file mode 100644 index e50b7452929dd2..00000000000000 --- a/packages/react-native/template/App.tsx +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Sample React Native App - * https://github.com/facebook/react-native - * - * @format - */ - -import React from 'react'; -import type {PropsWithChildren} from 'react'; -import {ScrollView, StyleSheet, Text, useColorScheme, View} from 'react-native'; - -import { - Colors, - DebugInstructions, - Header, - LearnMoreLinks, - ReloadInstructions, -} from 'react-native/Libraries/NewAppScreen'; - -type SectionProps = PropsWithChildren<{ - title: string; -}>; - -function Section({children, title}: SectionProps): React.JSX.Element { - const isDarkMode = useColorScheme() === 'dark'; - return ( - - - {title} - - - {children} - - - ); -} - -function App(): React.JSX.Element { - return ( - -
- -
- Edit App.tsx to change this - screen and then come back to see your edits. -
-
- -
-
- -
-
- Read the docs to discover what to do next: -
- -
- - ); -} - -const styles = StyleSheet.create({ - sectionContainer: { - marginTop: 32, - paddingHorizontal: 24, - }, - sectionTitle: { - fontSize: 24, - fontWeight: '600', - }, - sectionDescription: { - marginTop: 8, - fontSize: 18, - fontWeight: '400', - }, - highlight: { - fontWeight: '700', - }, -}); - -export default App; diff --git a/packages/react-native/template/metro.config.js b/packages/react-native/template/metro.config.js deleted file mode 100644 index d8a58b2b792d3d..00000000000000 --- a/packages/react-native/template/metro.config.js +++ /dev/null @@ -1,20 +0,0 @@ -const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config'); -const {getPlatformResolver} = require('@callstack/out-of-tree-platforms'); - -/** - * Metro configuration - * https://reactnative.dev/docs/metro - * - * @type {import('metro-config').MetroConfig} - */ - - -const config = { - resolver: { - resolveRequest: getPlatformResolver({ - platformNameMap: {visionos: '@callstack/react-native-visionos'}, - }), - }, -}; - -module.exports = mergeConfig(getDefaultConfig(__dirname), config); diff --git a/packages/react-native/template/package.json b/packages/react-native/template/package.json deleted file mode 100644 index 629f6ae71cdb46..00000000000000 --- a/packages/react-native/template/package.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "HelloWorld", - "version": "0.0.1", - "private": true, - "scripts": { - "android": "react-native run-android", - "ios": "react-native run-ios", - "visionos": "react-native run-visionos", - "lint": "eslint .", - "start": "react-native start", - "test": "jest" - }, - "dependencies": { - "react": "18.3.1", - "react-native": "1000.0.0", - "@callstack/react-native-visionos": "1000.0.0" - }, - "devDependencies": { - "@babel/core": "^7.20.0", - "@babel/preset-env": "^7.20.0", - "@babel/runtime": "^7.20.0", - "@react-native/babel-preset": "0.75.0-main", - "@react-native/eslint-config": "0.75.0-main", - "@react-native/metro-config": "0.75.0-main", - "@react-native/typescript-config": "0.75.0-main", - "@callstack/out-of-tree-platforms": "0.75.0-main", - "@types/react": "^18.2.6", - "@types/react-test-renderer": "^18.0.0", - "babel-jest": "^29.6.3", - "eslint": "^8.19.0", - "jest": "^29.6.3", - "prettier": "2.8.8", - "react-test-renderer": "18.3.1", - "typescript": "5.0.4" - }, - "engines": { - "node": ">=18" - } -} diff --git a/packages/react-native/template/visionos/HelloWorld.xcodeproj/project.pbxproj b/packages/react-native/template/visionos/HelloWorld.xcodeproj/project.pbxproj deleted file mode 100644 index b7d8ff5cd7e482..00000000000000 --- a/packages/react-native/template/visionos/HelloWorld.xcodeproj/project.pbxproj +++ /dev/null @@ -1,693 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 54; - objects = { - -/* Begin PBXBuildFile section */ - 00E356F31AD99517003FC87E /* HelloWorldTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* HelloWorldTests.m */; }; - 0C80B921A6F3F58F76C31292 /* libPods-HelloWorld.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-HelloWorld.a */; }; - 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; - 767CEBBC2B582F6B000139AD /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 767CEBBB2B582F6B000139AD /* AppDelegate.swift */; }; - 767CEBBE2B582F78000139AD /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 767CEBBD2B582F78000139AD /* App.swift */; }; - 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = PrivacyInfo.xcprivacy; path = HelloWorld/PrivacyInfo.xcprivacy; sourceTree = ""; }; - 7699B88040F8A987B510C191 /* libPods-HelloWorld-HelloWorldTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19F6CBCC0A4E27FBF8BF4A61 /* libPods-HelloWorld-HelloWorldTests.a */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 13B07F861A680F5B00A75B9A; - remoteInfo = HelloWorld; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 00E356EE1AD99517003FC87E /* HelloWorldTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HelloWorldTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 00E356F21AD99517003FC87E /* HelloWorldTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HelloWorldTests.m; sourceTree = ""; }; - 13B07F961A680F5B00A75B9A /* HelloWorld.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloWorld.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = HelloWorld/Images.xcassets; sourceTree = ""; }; - 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = HelloWorld/Info.plist; sourceTree = ""; }; - 19F6CBCC0A4E27FBF8BF4A61 /* libPods-HelloWorld-HelloWorldTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-HelloWorld-HelloWorldTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 3B4392A12AC88292D35C810B /* Pods-HelloWorld.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.debug.xcconfig"; path = "Target Support Files/Pods-HelloWorld/Pods-HelloWorld.debug.xcconfig"; sourceTree = ""; }; - 5709B34CF0A7D63546082F79 /* Pods-HelloWorld.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.release.xcconfig"; path = "Target Support Files/Pods-HelloWorld/Pods-HelloWorld.release.xcconfig"; sourceTree = ""; }; - 5B7EB9410499542E8C5724F5 /* Pods-HelloWorld-HelloWorldTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld-HelloWorldTests.debug.xcconfig"; path = "Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests.debug.xcconfig"; sourceTree = ""; }; - 5DCACB8F33CDC322A6C60F78 /* libPods-HelloWorld.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-HelloWorld.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 767CEBBB2B582F6B000139AD /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = HelloWorld/AppDelegate.swift; sourceTree = ""; }; - 767CEBBD2B582F78000139AD /* App.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = App.swift; path = HelloWorld/App.swift; sourceTree = ""; }; - 89C6BE57DB24E9ADA2F236DE /* Pods-HelloWorld-HelloWorldTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld-HelloWorldTests.release.xcconfig"; path = "Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests.release.xcconfig"; sourceTree = ""; }; - ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 00E356EB1AD99517003FC87E /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 7699B88040F8A987B510C191 /* libPods-HelloWorld-HelloWorldTests.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 0C80B921A6F3F58F76C31292 /* libPods-HelloWorld.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 00E356EF1AD99517003FC87E /* HelloWorldTests */ = { - isa = PBXGroup; - children = ( - 00E356F21AD99517003FC87E /* HelloWorldTests.m */, - 00E356F01AD99517003FC87E /* Supporting Files */, - ); - path = HelloWorldTests; - sourceTree = ""; - }; - 00E356F01AD99517003FC87E /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 00E356F11AD99517003FC87E /* Info.plist */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 13B07FAE1A68108700A75B9A /* HelloWorld */ = { - isa = PBXGroup; - children = ( - 767CEBBB2B582F6B000139AD /* AppDelegate.swift */, - 767CEBBD2B582F78000139AD /* App.swift */, - 13B07FB51A68108700A75B9A /* Images.xcassets */, - 13B07FB61A68108700A75B9A /* Info.plist */, - 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */, - ); - name = HelloWorld; - sourceTree = ""; - }; - 2D16E6871FA4F8E400B85C8A /* Frameworks */ = { - isa = PBXGroup; - children = ( - ED297162215061F000B7C4FE /* JavaScriptCore.framework */, - 5DCACB8F33CDC322A6C60F78 /* libPods-HelloWorld.a */, - 19F6CBCC0A4E27FBF8BF4A61 /* libPods-HelloWorld-HelloWorldTests.a */, - ); - name = Frameworks; - sourceTree = ""; - }; - 832341AE1AAA6A7D00B99B32 /* Libraries */ = { - isa = PBXGroup; - children = ( - ); - name = Libraries; - sourceTree = ""; - }; - 83CBB9F61A601CBA00E9B192 = { - isa = PBXGroup; - children = ( - 13B07FAE1A68108700A75B9A /* HelloWorld */, - 832341AE1AAA6A7D00B99B32 /* Libraries */, - 00E356EF1AD99517003FC87E /* HelloWorldTests */, - 83CBBA001A601CBA00E9B192 /* Products */, - 2D16E6871FA4F8E400B85C8A /* Frameworks */, - BBD78D7AC51CEA395F1C20DB /* Pods */, - ); - indentWidth = 2; - sourceTree = ""; - tabWidth = 2; - usesTabs = 0; - }; - 83CBBA001A601CBA00E9B192 /* Products */ = { - isa = PBXGroup; - children = ( - 13B07F961A680F5B00A75B9A /* HelloWorld.app */, - 00E356EE1AD99517003FC87E /* HelloWorldTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - BBD78D7AC51CEA395F1C20DB /* Pods */ = { - isa = PBXGroup; - children = ( - 3B4392A12AC88292D35C810B /* Pods-HelloWorld.debug.xcconfig */, - 5709B34CF0A7D63546082F79 /* Pods-HelloWorld.release.xcconfig */, - 5B7EB9410499542E8C5724F5 /* Pods-HelloWorld-HelloWorldTests.debug.xcconfig */, - 89C6BE57DB24E9ADA2F236DE /* Pods-HelloWorld-HelloWorldTests.release.xcconfig */, - ); - path = Pods; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 00E356ED1AD99517003FC87E /* HelloWorldTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "HelloWorldTests" */; - buildPhases = ( - A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */, - 00E356EA1AD99517003FC87E /* Sources */, - 00E356EB1AD99517003FC87E /* Frameworks */, - 00E356EC1AD99517003FC87E /* Resources */, - C59DA0FBD6956966B86A3779 /* [CP] Embed Pods Frameworks */, - F6A41C54EA430FDDC6A6ED99 /* [CP] Copy Pods Resources */, - ); - buildRules = ( - ); - dependencies = ( - 00E356F51AD99517003FC87E /* PBXTargetDependency */, - ); - name = HelloWorldTests; - productName = HelloWorldTests; - productReference = 00E356EE1AD99517003FC87E /* HelloWorldTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 13B07F861A680F5B00A75B9A /* HelloWorld */ = { - isa = PBXNativeTarget; - buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "HelloWorld" */; - buildPhases = ( - C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */, - 13B07F871A680F5B00A75B9A /* Sources */, - 13B07F8C1A680F5B00A75B9A /* Frameworks */, - 13B07F8E1A680F5B00A75B9A /* Resources */, - 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, - 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */, - E235C05ADACE081382539298 /* [CP] Copy Pods Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = HelloWorld; - productName = HelloWorld; - productReference = 13B07F961A680F5B00A75B9A /* HelloWorld.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 83CBB9F71A601CBA00E9B192 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1210; - TargetAttributes = { - 00E356ED1AD99517003FC87E = { - CreatedOnToolsVersion = 6.2; - TestTargetID = 13B07F861A680F5B00A75B9A; - }; - 13B07F861A680F5B00A75B9A = { - LastSwiftMigration = 1120; - }; - }; - }; - buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "HelloWorld" */; - compatibilityVersion = "Xcode 12.0"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 83CBB9F61A601CBA00E9B192; - productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 13B07F861A680F5B00A75B9A /* HelloWorld */, - 00E356ED1AD99517003FC87E /* HelloWorldTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 00E356EC1AD99517003FC87E /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 13B07F8E1A680F5B00A75B9A /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "$(SRCROOT)/.xcode.env.local", - "$(SRCROOT)/.xcode.env", - ); - name = "Bundle React Native code and images"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/@callstack/react-native-visionos/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/@callstack/react-native-visionos/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n"; - }; - 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-HelloWorld/Pods-HelloWorld-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-HelloWorld/Pods-HelloWorld-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-HelloWorld/Pods-HelloWorld-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-HelloWorld-HelloWorldTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-HelloWorld-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - C59DA0FBD6956966B86A3779 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - E235C05ADACE081382539298 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-HelloWorld/Pods-HelloWorld-resources-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-HelloWorld/Pods-HelloWorld-resources-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-HelloWorld/Pods-HelloWorld-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - F6A41C54EA430FDDC6A6ED99 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests-resources-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests-resources-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 00E356EA1AD99517003FC87E /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 00E356F31AD99517003FC87E /* HelloWorldTests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 13B07F871A680F5B00A75B9A /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 767CEBBC2B582F6B000139AD /* AppDelegate.swift in Sources */, - 767CEBBE2B582F78000139AD /* App.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 00E356F51AD99517003FC87E /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 13B07F861A680F5B00A75B9A /* HelloWorld */; - targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 00E356F61AD99517003FC87E /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 5B7EB9410499542E8C5724F5 /* Pods-HelloWorld-HelloWorldTests.debug.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - INFOPLIST_FILE = HelloWorldTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 13.4; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - OTHER_LDFLAGS = ( - "-ObjC", - "-lc++", - "$(inherited)", - ); - PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HelloWorld.app/HelloWorld"; - }; - name = Debug; - }; - 00E356F71AD99517003FC87E /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 89C6BE57DB24E9ADA2F236DE /* Pods-HelloWorld-HelloWorldTests.release.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - COPY_PHASE_STRIP = NO; - INFOPLIST_FILE = HelloWorldTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 13.4; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - OTHER_LDFLAGS = ( - "-ObjC", - "-lc++", - "$(inherited)", - ); - PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HelloWorld.app/HelloWorld"; - }; - name = Release; - }; - 13B07F941A680F5B00A75B9A /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-HelloWorld.debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 1; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = HelloWorld/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - MARKETING_VERSION = 1.0; - OTHER_LDFLAGS = ( - "$(inherited)", - "-ObjC", - "-lc++", - ); - PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = HelloWorld; - SUPPORTED_PLATFORMS = "xros xrsimulator"; - SUPPORTS_MACCATALYST = NO; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; - SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = 7; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Debug; - }; - 13B07F951A680F5B00A75B9A /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-HelloWorld.release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 1; - INFOPLIST_FILE = HelloWorld/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - MARKETING_VERSION = 1.0; - OTHER_LDFLAGS = ( - "$(inherited)", - "-ObjC", - "-lc++", - ); - PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = HelloWorld; - SUPPORTED_PLATFORMS = "xros xrsimulator"; - SUPPORTS_MACCATALYST = NO; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; - SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = 7; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Release; - }; - 83CBBA201A601CBA00E9B192 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_CXX_LANGUAGE_STANDARD = "c++20"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = ""; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.4; - LD_RUNPATH_SEARCH_PATHS = ( - /usr/lib/swift, - "$(inherited)", - ); - LIBRARY_SEARCH_PATHS = ( - "\"$(SDKROOT)/usr/lib/swift\"", - "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"", - "\"$(inherited)\"", - ); - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - OTHER_CPLUSPLUSFLAGS = ( - "$(OTHER_CFLAGS)", - "-DFOLLY_NO_CONFIG", - "-DFOLLY_MOBILE=1", - "-DFOLLY_USE_LIBCPP=1", - "-DFOLLY_CFG_NO_COROUTINES=1", - "-DFOLLY_HAVE_CLOCK_GETTIME=1", - ); - SDKROOT = iphoneos; - }; - name = Debug; - }; - 83CBBA211A601CBA00E9B192 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_CXX_LANGUAGE_STANDARD = "c++20"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = YES; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = ""; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.4; - LD_RUNPATH_SEARCH_PATHS = ( - /usr/lib/swift, - "$(inherited)", - ); - LIBRARY_SEARCH_PATHS = ( - "\"$(SDKROOT)/usr/lib/swift\"", - "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"", - "\"$(inherited)\"", - ); - MTL_ENABLE_DEBUG_INFO = NO; - OTHER_CPLUSPLUSFLAGS = ( - "$(OTHER_CFLAGS)", - "-DFOLLY_NO_CONFIG", - "-DFOLLY_MOBILE=1", - "-DFOLLY_USE_LIBCPP=1", - "-DFOLLY_CFG_NO_COROUTINES=1", - "-DFOLLY_HAVE_CLOCK_GETTIME=1", - ); - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "HelloWorldTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 00E356F61AD99517003FC87E /* Debug */, - 00E356F71AD99517003FC87E /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "HelloWorld" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 13B07F941A680F5B00A75B9A /* Debug */, - 13B07F951A680F5B00A75B9A /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "HelloWorld" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 83CBBA201A601CBA00E9B192 /* Debug */, - 83CBBA211A601CBA00E9B192 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; -} diff --git a/packages/react-native/template/visionos/HelloWorld.xcodeproj/xcshareddata/xcschemes/HelloWorld.xcscheme b/packages/react-native/template/visionos/HelloWorld.xcodeproj/xcshareddata/xcschemes/HelloWorld.xcscheme deleted file mode 100644 index b57be22ab2d66f..00000000000000 --- a/packages/react-native/template/visionos/HelloWorld.xcodeproj/xcshareddata/xcschemes/HelloWorld.xcscheme +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/react-native/template/visionos/HelloWorld/App.swift b/packages/react-native/template/visionos/HelloWorld/App.swift deleted file mode 100644 index c1d601b2201ba9..00000000000000 --- a/packages/react-native/template/visionos/HelloWorld/App.swift +++ /dev/null @@ -1,12 +0,0 @@ -import SwiftUI -import React -import React_RCTSwiftExtensions - -@main -struct HelloWorldApp: App { - @UIApplicationDelegateAdaptor var delegate: AppDelegate - - var body: some Scene { - RCTMainWindow(moduleName: "HelloWorld") - } -} diff --git a/packages/react-native/template/visionos/HelloWorld/AppDelegate.swift b/packages/react-native/template/visionos/HelloWorld/AppDelegate.swift deleted file mode 100644 index 4e68fb4c1bd7ab..00000000000000 --- a/packages/react-native/template/visionos/HelloWorld/AppDelegate.swift +++ /dev/null @@ -1,17 +0,0 @@ -import UIKit -import React -import React_RCTAppDelegate - -class AppDelegate: RCTAppDelegate { - override func sourceURL(for bridge: RCTBridge) -> URL? { - self.bundleURL() - } - - override func bundleURL() -> URL? { -#if DEBUG - RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index") -#else - Bundle.main.url(forResource: "main", withExtension: "jsbundle") -#endif - } -} diff --git a/packages/react-native/template/visionos/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json b/packages/react-native/template/visionos/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 81213230deb40d..00000000000000 --- a/packages/react-native/template/visionos/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "20x20" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "20x20" - }, - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "29x29" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "29x29" - }, - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "40x40" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "40x40" - }, - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "60x60" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "60x60" - }, - { - "idiom" : "ios-marketing", - "scale" : "1x", - "size" : "1024x1024" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/packages/react-native/template/visionos/HelloWorld/Images.xcassets/Contents.json b/packages/react-native/template/visionos/HelloWorld/Images.xcassets/Contents.json deleted file mode 100644 index 2d92bd53fdb222..00000000000000 --- a/packages/react-native/template/visionos/HelloWorld/Images.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/packages/react-native/template/visionos/HelloWorld/Info.plist b/packages/react-native/template/visionos/HelloWorld/Info.plist deleted file mode 100644 index 2f57133ef1d075..00000000000000 --- a/packages/react-native/template/visionos/HelloWorld/Info.plist +++ /dev/null @@ -1,57 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleDisplayName - Hello App Display Name - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - $(MARKETING_VERSION) - CFBundleSignature - ???? - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - LSRequiresIPhoneOS - - NSAppTransportSecurity - - - NSAllowsArbitraryLoads - - NSAllowsLocalNetworking - - - NSLocationWhenInUseUsageDescription - - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - UIApplicationSceneManifest - - UIApplicationSupportsMultipleScenes - - UISceneConfigurations - - - - diff --git a/packages/react-native/template/visionos/HelloWorld/PrivacyInfo.xcprivacy b/packages/react-native/template/visionos/HelloWorld/PrivacyInfo.xcprivacy deleted file mode 100644 index ef1896e70c88da..00000000000000 --- a/packages/react-native/template/visionos/HelloWorld/PrivacyInfo.xcprivacy +++ /dev/null @@ -1,38 +0,0 @@ - - - - - NSPrivacyCollectedDataTypes - - - NSPrivacyAccessedAPITypes - - - NSPrivacyAccessedAPIType - NSPrivacyAccessedAPICategoryFileTimestamp - NSPrivacyAccessedAPITypeReasons - - C617.1 - - - - NSPrivacyAccessedAPIType - NSPrivacyAccessedAPICategoryUserDefaults - NSPrivacyAccessedAPITypeReasons - - CA92.1 - - - - NSPrivacyAccessedAPIType - NSPrivacyAccessedAPICategorySystemBootTime - NSPrivacyAccessedAPITypeReasons - - 35F9.1 - - - - NSPrivacyTracking - - - diff --git a/packages/react-native/template/visionos/HelloWorldTests/HelloWorldTests.m b/packages/react-native/template/visionos/HelloWorldTests/HelloWorldTests.m deleted file mode 100644 index 884d405d6579c6..00000000000000 --- a/packages/react-native/template/visionos/HelloWorldTests/HelloWorldTests.m +++ /dev/null @@ -1,66 +0,0 @@ -#import -#import - -#import -#import - -#define TIMEOUT_SECONDS 600 -#define TEXT_TO_LOOK_FOR @"Welcome to React" - -@interface HelloWorldTests : XCTestCase - -@end - -@implementation HelloWorldTests - -- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test -{ - if (test(view)) { - return YES; - } - for (UIView *subview in [view subviews]) { - if ([self findSubviewInView:subview matching:test]) { - return YES; - } - } - return NO; -} - -- (void)testRendersWelcomeScreen -{ - UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; - NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; - BOOL foundElement = NO; - - __block NSString *redboxError = nil; -#ifdef DEBUG - RCTSetLogFunction( - ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { - if (level >= RCTLogLevelError) { - redboxError = message; - } - }); -#endif - - while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { - [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; - [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; - - foundElement = [self findSubviewInView:vc.view - matching:^BOOL(UIView *view) { - if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { - return YES; - } - return NO; - }]; - } - -#ifdef DEBUG - RCTSetLogFunction(RCTDefaultLogFunction); -#endif - - XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); - XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); -} - -@end diff --git a/packages/react-native/template/visionos/HelloWorldTests/Info.plist b/packages/react-native/template/visionos/HelloWorldTests/Info.plist deleted file mode 100644 index ba72822e8728ef..00000000000000 --- a/packages/react-native/template/visionos/HelloWorldTests/Info.plist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - - diff --git a/packages/react-native/template/visionos/Podfile b/packages/react-native/template/visionos/Podfile deleted file mode 100644 index c6d5ba6c29b336..00000000000000 --- a/packages/react-native/template/visionos/Podfile +++ /dev/null @@ -1,40 +0,0 @@ -# Resolve react_native_pods.rb with node to allow for hoisting -require Pod::Executable.execute_command('node', ['-p', - 'require.resolve( - "@callstack/react-native-visionos/scripts/react_native_pods.rb", - {paths: [process.argv[1]]}, - )', __dir__]).strip - -platform :visionos, min_visionos_version_supported -prepare_react_native_project! - -linkage = ENV['USE_FRAMEWORKS'] -if linkage != nil - Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green - use_frameworks! :linkage => linkage.to_sym -end - -target 'HelloWorld' do - config = use_native_modules! - config[:reactNativePath] = '../node_modules/@callstack/react-native-visionos' - - use_react_native!( - :path => config[:reactNativePath], - # An absolute path to your application root. - :app_path => "#{Pod::Config.instance.installation_root}/.." - ) - - target 'HelloWorldTests' do - inherit! :complete - # Pods for testing - end - - post_install do |installer| - # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 - react_native_post_install( - installer, - config[:reactNativePath], - :mac_catalyst_enabled => false - ) - end -end diff --git a/packages/react-native/template/visionos/_xcode.env b/packages/react-native/template/visionos/_xcode.env deleted file mode 100644 index 3d5782c71568d3..00000000000000 --- a/packages/react-native/template/visionos/_xcode.env +++ /dev/null @@ -1,11 +0,0 @@ -# This `.xcode.env` file is versioned and is used to source the environment -# used when running script phases inside Xcode. -# To customize your local environment, you can create an `.xcode.env.local` -# file that is not versioned. - -# NODE_BINARY variable contains the PATH to the node executable. -# -# Customize the NODE_BINARY variable here. -# For example, to use nvm with brew, add the following line -# . "$(brew --prefix nvm)/nvm.sh" --no-use -export NODE_BINARY=$(command -v node) diff --git a/packages/react-native/third-party-podspecs/SocketRocket.podspec b/packages/react-native/third-party-podspecs/SocketRocket.podspec deleted file mode 100644 index 7e65ab07b1710a..00000000000000 --- a/packages/react-native/third-party-podspecs/SocketRocket.podspec +++ /dev/null @@ -1,21 +0,0 @@ -Pod::Spec.new do |s| - s.name = 'SocketRocket' - s.version = '0.7.0.1' - s.summary = 'A conforming WebSocket (RFC 6455) client library for iOS, macOS and tvOS.' - s.homepage = 'https://github.com/facebook/SocketRocket' - s.authors = { 'Nikita Lutsenko' => 'nlutsenko@me.com', 'Dan Federman' => 'federman@squareup.com', 'Mike Lewis' => 'mikelikespie@gmail.com' } - s.license = 'BSD' - s.source = { :git => 'https://github.com/facebook/SocketRocket.git', :tag => '0.7.0' } - s.requires_arc = true - - s.source_files = 'SocketRocket/**/*.{h,m}' - s.public_header_files = 'SocketRocket/*.h' - - s.platforms = min_supported_versions - - s.ios.frameworks = 'CFNetwork', 'Security' - s.osx.frameworks = 'CoreServices', 'Security' - s.tvos.frameworks = 'CFNetwork', 'Security' - s.visionos.frameworks = 'CFNetwork', 'Security' - s.libraries = 'icucore' - end \ No newline at end of file diff --git a/packages/react-native/types/index.d.ts b/packages/react-native/types/index.d.ts index 917b5cc65d098d..5c89c19b97c707 100644 --- a/packages/react-native/types/index.d.ts +++ b/packages/react-native/types/index.d.ts @@ -148,6 +148,7 @@ export * from '../Libraries/Utilities/PixelRatio'; export * from '../Libraries/Utilities/Platform'; export * from '../Libraries/Vibration/Vibration'; export * from '../Libraries/XR/XR'; +export * from '../Libraries/WindowManager/WindowManager'; export * from '../Libraries/YellowBox/YellowBoxDeprecated'; export * from '../Libraries/vendor/core/ErrorUtils'; export { diff --git a/packages/react-native/visionos_modules/NativeWindowManager.js b/packages/react-native/visionos_modules/NativeWindowManager.js new file mode 100644 index 00000000000000..0ec16cfe85d6e2 --- /dev/null +++ b/packages/react-native/visionos_modules/NativeWindowManager.js @@ -0,0 +1,24 @@ +/** + * @flow strict + * @format + */ + +import type {TurboModule} from '../Libraries/TurboModule/RCTExport'; + +import * as TurboModuleRegistry from '../Libraries/TurboModule/TurboModuleRegistry'; + +export type WindowManagerConstants = {| + +supportsMultipleScenes?: boolean, +|}; + +export interface Spec extends TurboModule { + +getConstants: () => WindowManagerConstants; + + // $FlowIgnore[unclear-type] + +openWindow: (windowId: string, userInfo: Object) => Promise; + // $FlowIgnore[unclear-type] + +updateWindow: (windowId: string, userInfo: Object) => Promise; + +closeWindow: (windowId: string) => Promise; +} + +export default (TurboModuleRegistry.get('WindowManager'): ?Spec); diff --git a/packages/react-native/visionos_modules/NativeXRModule.js b/packages/react-native/visionos_modules/NativeXRModule.js new file mode 100644 index 00000000000000..bd0b3948539183 --- /dev/null +++ b/packages/react-native/visionos_modules/NativeXRModule.js @@ -0,0 +1,16 @@ +/** + * @flow strict + * @format + */ + +import type {TurboModule} from '../Libraries/TurboModule/RCTExport'; + +import * as TurboModuleRegistry from '../Libraries/TurboModule/TurboModuleRegistry'; + +export interface Spec extends TurboModule { + // $FlowIgnore[unclear-type] + +requestSession: (sessionId?: string, userInfo: Object) => Promise; + +endSession: () => Promise; +} + +export default (TurboModuleRegistry.get('XRModule'): ?Spec); diff --git a/packages/rn-tester/Podfile.lock b/packages/rn-tester/Podfile.lock index b64e9db2f88d07..2c2fbba4de08b8 100644 --- a/packages/rn-tester/Podfile.lock +++ b/packages/rn-tester/Podfile.lock @@ -14,16 +14,17 @@ PODS: - RCT-Folly (= 2024.01.01.00) - RCTRequired - RCTTypeSafety - - React-Codegen - React-Core - React-debug - React-Fabric + - React-featureflags - React-graphics - React-ImageManager - React-NativeModulesApple - React-RCTFabric - React-rendererdebug - React-utils + - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga @@ -56,16 +57,17 @@ PODS: - RCT-Folly (= 2024.01.01.00) - RCTRequired - RCTTypeSafety - - React-Codegen - React-Core - React-debug - React-Fabric + - React-featureflags - React-graphics - React-ImageManager - React-NativeModulesApple - React-RCTFabric - React-rendererdebug - React-utils + - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga @@ -112,9 +114,11 @@ PODS: - RCTDeprecation - React-Core/Default (= 0.76.0) - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -127,9 +131,11 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -141,10 +147,11 @@ PODS: - RCT-Folly (= 2024.01.01.00) - RCTDeprecation - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor - - React-jsinspector (= 1000.0.0) + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -158,10 +165,11 @@ PODS: - React-Core/Default (= 0.76.0) - React-Core/RCTWebSocket (= 0.76.0) - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor - - React-jsinspector (= 1000.0.0) + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -174,9 +182,11 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -189,9 +199,11 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -204,9 +216,11 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -219,9 +233,11 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -234,9 +250,11 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -249,9 +267,11 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -264,9 +284,11 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -279,9 +301,11 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -294,9 +318,11 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -309,9 +335,11 @@ PODS: - RCTDeprecation - React-Core/Default - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -324,6 +352,41 @@ PODS: - RCTDeprecation - React-Core/Default (= 0.76.0) - React-cxxreact + - React-featureflags + - React-hermes + - React-jsi + - React-jsiexecutor + - React-jsinspector + - React-perflogger + - React-runtimescheduler + - React-utils + - SocketRocket (= 0.7.1) + - Yoga + - React-Core/RCTWindowManagerHeaders (1000.0.0): + - glog + - hermes-engine + - RCT-Folly (= 2024.01.01.00) + - RCTDeprecation + - React-Core/Default + - React-cxxreact + - React-featureflags + - React-hermes + - React-jsi + - React-jsiexecutor + - React-jsinspector + - React-perflogger + - React-runtimescheduler + - React-utils + - SocketRocket (= 0.7.1) + - Yoga + - React-Core/RCTXRHeaders (1000.0.0): + - glog + - hermes-engine + - RCT-Folly (= 2024.01.01.00) + - RCTDeprecation + - React-Core/Default + - React-cxxreact + - React-featureflags - React-hermes - React-jsi - React-jsiexecutor @@ -456,6 +519,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -475,6 +539,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -494,6 +559,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -513,6 +579,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -555,6 +622,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -574,6 +642,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -593,6 +662,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -613,6 +683,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -652,6 +723,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -671,6 +743,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -690,6 +763,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -730,6 +804,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -771,6 +846,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -790,6 +866,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-featureflags - React-graphics - React-jsi - React-jsiexecutor @@ -1173,7 +1250,8 @@ PODS: - fmt (= 9.1.0) - glog - RCT-Folly/Fabric (= 2024.01.01.00) - - React-Core/Default (= 1000.0.0) + - React-jsi + - React-jsiexecutor - React-utils - React-hermes (0.76.0): - DoubleConversion @@ -1245,6 +1323,7 @@ PODS: - React-jsinspector (0.76.0): - DoubleConversion - glog + - hermes-engine - RCT-Folly (= 2024.01.01.00) - React-featureflags - React-jsi @@ -1286,6 +1365,7 @@ PODS: - React-Core - React-cxxreact - React-jsi + - React-jsinspector - React-runtimeexecutor - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core @@ -1301,10 +1381,10 @@ PODS: - React-RCTAnimation (0.76.0): - RCT-Folly (= 2024.01.01.00) - RCTTypeSafety - - React-Codegen - React-Core/RCTAnimationHeaders - React-jsi - React-NativeModulesApple + - ReactCodegen - ReactCommon - React-RCTAppDelegate (0.76.0): - RCT-Folly (= 2024.01.01.00) @@ -1329,18 +1409,20 @@ PODS: - React-RuntimeHermes - React-runtimescheduler - React-utils + - ReactCodegen - ReactCommon - React-RCTBlob (0.76.0): - DoubleConversion - fmt (= 9.1.0) - hermes-engine - RCT-Folly (= 2024.01.01.00) - - React-Codegen - React-Core/RCTBlobHeaders - React-Core/RCTWebSocket - React-jsi + - React-jsinspector - React-NativeModulesApple - React-RCTNetwork + - ReactCodegen - ReactCommon - React-RCTFabric (0.76.0): - glog @@ -1351,9 +1433,11 @@ PODS: - React-Fabric - React-FabricComponents - React-FabricImage + - React-featureflags - React-graphics - React-ImageManager - React-jsi + - React-jsinspector - React-nativeconfig - React-performancetimeline - React-RCTImage @@ -1366,40 +1450,41 @@ PODS: - React-RCTImage (0.76.0): - RCT-Folly (= 2024.01.01.00) - RCTTypeSafety - - React-Codegen - React-Core/RCTImageHeaders - React-jsi - React-NativeModulesApple - React-RCTNetwork + - ReactCodegen - ReactCommon - React-RCTLinking (0.76.0): - React-Core/RCTLinkingHeaders (= 0.76.0) - React-jsi (= 0.76.0) - React-NativeModulesApple + - ReactCodegen - ReactCommon - ReactCommon/turbomodule/core (= 0.76.0) - React-RCTNetwork (0.76.0): - RCT-Folly (= 2024.01.01.00) - RCTTypeSafety - - React-Codegen - React-Core/RCTNetworkHeaders - React-jsi - React-NativeModulesApple + - ReactCodegen - ReactCommon - React-RCTPushNotification (0.76.0): - RCTTypeSafety - - React-Codegen - React-Core/RCTPushNotificationHeaders - React-jsi - React-NativeModulesApple + - ReactCodegen - ReactCommon - React-RCTSettings (0.76.0): - RCT-Folly (= 2024.01.01.00) - RCTTypeSafety - - React-Codegen - React-Core/RCTSettingsHeaders - React-jsi - React-NativeModulesApple + - ReactCodegen - ReactCommon - React-RCTTest (0.76.0): - RCT-Folly (= 2024.01.01.00) @@ -1412,7 +1497,6 @@ PODS: - Yoga - React-RCTVibration (0.76.0): - RCT-Folly (= 2024.01.01.00) - - React-Codegen - React-Core/RCTVibrationHeaders - React-jsi - React-NativeModulesApple @@ -1449,6 +1533,7 @@ PODS: - hermes-engine - RCT-Folly/Fabric (= 2024.01.01.00) - React-cxxreact + - React-featureflags - React-jserrorhandler - React-jsi - React-jsiexecutor @@ -1462,7 +1547,10 @@ PODS: - React-RuntimeHermes (0.76.0): - hermes-engine - RCT-Folly/Fabric (= 2024.01.01.00) + - React-featureflags + - React-hermes - React-jsi + - React-jsinspector - React-jsitracing - React-nativeconfig - React-RuntimeCore @@ -1474,6 +1562,7 @@ PODS: - React-callinvoker - React-cxxreact - React-debug + - React-featureflags - React-jsi - React-performancetimeline - React-rendererconsistency @@ -1484,6 +1573,7 @@ PODS: - React-timing (0.76.0) - React-utils (0.76.0): - glog + - hermes-engine - RCT-Folly (= 2024.01.01.00) - React-debug - React-jsi (= 0.76.0) @@ -1514,11 +1604,11 @@ PODS: - fmt (= 9.1.0) - hermes-engine - RCT-Folly - - React-Codegen - React-Core - React-cxxreact - React-jsi - React-NativeModulesApple + - ReactCodegen - ReactCommon - ReactCommon/turbomodule (0.76.0): - DoubleConversion @@ -1565,16 +1655,17 @@ PODS: - RCT-Folly (= 2024.01.01.00) - RCTRequired - RCTTypeSafety - - React-Codegen - React-Core - React-debug - React-Fabric + - React-featureflags - React-graphics - React-ImageManager - React-NativeModulesApple - React-RCTFabric - React-rendererdebug - React-utils + - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga @@ -1590,7 +1681,7 @@ DEPENDENCIES: - hermes-engine (from `../react-native/sdks/hermes-engine/hermes-engine.podspec`) - MyNativeView (from `NativeComponentExample`) - NativeCxxModuleExample (from `NativeCxxModuleExample`) - - OCMock (~> 3.9.1) + - OCMock (from `https://github.com/erikdoe/ocmock.git`, tag `v3.9.2`) - OSSLibraryExample (from `../react-native-test-library`) - RCT-Folly (from `../react-native/third-party-podspecs/RCT-Folly.podspec`) - RCT-Folly/Fabric (from `../react-native/third-party-podspecs/RCT-Folly.podspec`) @@ -1599,7 +1690,6 @@ DEPENDENCIES: - RCTTypeSafety (from `../react-native/Libraries/TypeSafety`) - React (from `../react-native/`) - React-callinvoker (from `../react-native/ReactCommon/callinvoker`) - - React-Codegen (from `build/generated/ios`) - React-Core (from `../react-native/`) - React-Core/RCTWebSocket (from `../react-native/`) - React-CoreModules (from `../react-native/React/CoreModules`) @@ -1610,6 +1700,8 @@ DEPENDENCIES: - React-Fabric (from `../react-native/ReactCommon`) - React-FabricComponents (from `../react-native/ReactCommon`) - React-FabricImage (from `../react-native/ReactCommon`) + - React-featureflags (from `../react-native/ReactCommon/react/featureflags`) + - React-featureflagsnativemodule (from `../react-native/ReactCommon/react/nativemodule/featureflags`) - React-graphics (from `../react-native/ReactCommon/react/renderer/graphics`) - React-hermes (from `../react-native/ReactCommon/hermes`) - React-idlecallbacksnativemodule (from `../react-native/ReactCommon/react/nativemodule/idlecallbacks`) @@ -1621,6 +1713,7 @@ DEPENDENCIES: - React-jsitracing (from `../react-native/ReactCommon/hermes/executor/`) - React-logger (from `../react-native/ReactCommon/logger`) - React-Mapbuffer (from `../react-native/ReactCommon`) + - React-microtasksnativemodule (from `../react-native/ReactCommon/react/nativemodule/microtasks`) - React-nativeconfig (from `../react-native/ReactCommon`) - React-NativeModulesApple (from `../react-native/ReactCommon/react/nativemodule/core/platform/ios`) - React-perflogger (from `../react-native/ReactCommon/reactperflogger`) @@ -1651,12 +1744,16 @@ DEPENDENCIES: - React-runtimescheduler (from `../react-native/ReactCommon/react/renderer/runtimescheduler`) - React-timing (from `../react-native/ReactCommon/react/timing`) - React-utils (from `../react-native/ReactCommon/react/utils`) + - ReactCodegen (from `build/generated/ios`) - ReactCommon-Samples (from `../react-native/ReactCommon/react/nativemodule/samples`) - ReactCommon/turbomodule/core (from `../react-native/ReactCommon`) - ScreenshotManager (from `NativeModuleExample`) - - SocketRocket (from `../react-native/third-party-podspecs/SocketRocket.podspec`) - Yoga (from `../react-native/ReactCommon/yoga`) +SPEC REPOS: + trunk: + - SocketRocket + EXTERNAL SOURCES: boost: :podspec: "../react-native/third-party-podspecs/boost.podspec" @@ -1675,6 +1772,9 @@ EXTERNAL SOURCES: :path: NativeComponentExample NativeCxxModuleExample: :path: NativeCxxModuleExample + OCMock: + :git: https://github.com/erikdoe/ocmock.git + :tag: v3.9.2 OSSLibraryExample: :path: "../react-native-test-library" RCT-Folly: @@ -1689,8 +1789,6 @@ EXTERNAL SOURCES: :path: "../react-native/" React-callinvoker: :path: "../react-native/ReactCommon/callinvoker" - React-Codegen: - :path: build/generated/ios React-Core: :path: "../react-native/" React-CoreModules: @@ -1709,6 +1807,10 @@ EXTERNAL SOURCES: :path: "../react-native/ReactCommon" React-FabricImage: :path: "../react-native/ReactCommon" + React-featureflags: + :path: "../react-native/ReactCommon/react/featureflags" + React-featureflagsnativemodule: + :path: "../react-native/ReactCommon/react/nativemodule/featureflags" React-graphics: :path: "../react-native/ReactCommon/react/renderer/graphics" React-hermes: @@ -1731,6 +1833,8 @@ EXTERNAL SOURCES: :path: "../react-native/ReactCommon/logger" React-Mapbuffer: :path: "../react-native/ReactCommon" + React-microtasksnativemodule: + :path: "../react-native/ReactCommon/react/nativemodule/microtasks" React-nativeconfig: :path: "../react-native/ReactCommon" React-NativeModulesApple: @@ -1791,14 +1895,14 @@ EXTERNAL SOURCES: :path: "../react-native/ReactCommon/react/timing" React-utils: :path: "../react-native/ReactCommon/react/utils" + ReactCodegen: + :path: build/generated/ios ReactCommon: :path: "../react-native/ReactCommon" ReactCommon-Samples: :path: "../react-native/ReactCommon/react/nativemodule/samples" ScreenshotManager: :path: NativeModuleExample - SocketRocket: - :podspec: "../react-native/third-party-podspecs/SocketRocket.podspec" Yoga: :path: "../react-native/ReactCommon/yoga" @@ -1876,6 +1980,83 @@ SPEC CHECKSUMS: SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 Yoga: 1d66db49f38fd9e576a1d7c3b081e46ab4c28b9e -PODFILE CHECKSUM: 8591f96a513620a2a83a0b9a125ad3fa32ea1369 +SPEC CHECKSUMS: + boost: 860c623744dab87c609a055f83f83f42b5ebcc72 + DoubleConversion: 55b1a13a4ac0adb3284bef5f3f0c96754f6f0ae8 + FBLazyVector: 75917a8d89cfe57b7f98cd4ab36cb526f1174cd7 + fmt: 030bf7157445bf1aea48da271f274f4414e75349 + glog: a40a7f15eed93736148eb4c5bb7ed8a4a460f748 + hermes-engine: 6122c86dee17ba201cb2319a3f482ce0b1e1a7ae + MyNativeView: 4aaf4bcf87cc036f198a87515b761bedc3485559 + NativeCxxModuleExample: 6205ec76b01387bae46348010610ee14e4263038 + OCMock: 267d92c078398b7ce11d99e811e3a402744c06bc + OSSLibraryExample: 2142d01ef5f40e317ad354d2801552774682c7f1 + RCT-Folly: d23913eeafd2fd092ae5067925f4b778c33dadf9 + RCTDeprecation: 3808e36294137f9ee5668f4df2e73dc079cd1dcf + RCTRequired: 8919b4dc424a86aba972804530a06910b74d15a5 + RCTTypeSafety: 3f1a45e4577f09e87afa7a96aa626f39303eda82 + React: e4ed2cd942dd3e28e922468afaf73868de21ea27 + React-callinvoker: d6a336a05b014e411ea16c6cddaa6d59e1a5b0bc + React-Core: 492bd6177faf25b49f26318a315aa0ac1ba38d96 + React-CoreModules: c85b9b284f3382f0c800ee9e0bb39ca2de770e8d + React-cxxreact: 8de3c541a2252614df9ef5f6f10da47de049f894 + React-debug: 6f947fa4a7419c21c162c9803c6f3f24d6b7e68c + React-defaultsnativemodule: 10b757a10362c6eacbe5ad38a5e98504fc5e4798 + React-domnativemodule: a9d107632f08c9c0792c1d8c9e8608729b3e600d + React-Fabric: f9dab36edff6834e99750add3a59058353687c79 + React-FabricComponents: 6692268833fdb0ec9e435611bf8ea1e7faacc0e1 + React-FabricImage: 6417f376e21ad0f58894e628867163b5a3327f69 + React-featureflags: 7ec38e7f4b81a870e7c4912c4eb02a726384db6d + React-featureflagsnativemodule: f6a3befd63d4e27bee813e9321643dbed6800543 + React-graphics: eba6d6369336f25baba841534d919f8d52ea8be6 + React-hermes: 336332b5fc7625c90d27820371d5d20f2ab8dd5b + React-idlecallbacksnativemodule: 16b079c2f21c7f8ba0b4c242a46bf00d06a9d7c6 + React-ImageManager: 05a3c1a062d90df2181458c0d0665a8ffa084244 + React-jserrorhandler: 88322945d8c68834e22511963c4ddc644ca7535d + React-jsi: b0b8226b325d9a5d4ee792b097da4061f3a5e3f7 + React-jsiexecutor: 166248bb49a62884118be80414f0a8958ae577a3 + React-jsinspector: 4aad8ab68d7da02ee74902575b9f0a68bfc42189 + React-jsitracing: b632400ca03d0554d482ffc254b4a4e1ab6024a7 + React-logger: 35584107dc831ae3bc23064c63161c0a079f959b + React-Mapbuffer: 8faa20ad9065b2d09c321c2387257780d3041863 + React-microtasksnativemodule: 9ba80052db25065c66234b326de431912df19545 + React-nativeconfig: be3975ef2d52d63ac255ecbf1861f9ef7b60b439 + React-NativeModulesApple: e6a958f9925095363c22f4343337bf8f0227ca49 + React-perflogger: 3e6acd6b92b0ea8ccd5a0872edfe70ebdecfe6bd + React-performancetimeline: 369a6ed47a5f951586d7b4dd741382ec8307080f + React-RCTActionSheet: 6df066b08fa19696b19e8a0b500c24f09a8238d5 + React-RCTAnimation: 2a52d8345af047b8fe2ce8fe9c7ef1b12876081a + React-RCTAppDelegate: 0181d89af0fb8aca50b41749a2952d102d31dc8d + React-RCTBlob: b70a36038f80af467052b7b0966d9d3403d538a4 + React-RCTFabric: c07a979acbda5fee3da9a67689cc549830a2cf07 + React-RCTImage: 9b63b595bf2aa575383fb978ce3ade3cedb95ba7 + React-RCTLinking: 442be15b86fd627fc9eff11b82996608072e93f5 + React-RCTNetwork: ced688e676899e4e1cde14d070db16721855867c + React-RCTPushNotification: 547e8526b4878bb0dc1cc73a3631ee9222d301a4 + React-RCTSettings: ef1b0340fbcbcbd83cb787c6c64f8ec87f93fd02 + React-RCTSwiftExtensions: 5b6189006b9e5526390b1f88168b5e9ac5b5f8ec + React-RCTTest: fe0371b6bb5703e5dbdc145d704f3db0dd99a6c6 + React-RCTText: f8ef84e0c01ff4a463d8984e13f02d8cb3489e67 + React-RCTVibration: ce3dfe8bcb777d8e694a8b643a72b78fb4e9a035 + React-RCTWindowManager: a53b985b4a923e13c1ab7546e87db04bb1956300 + React-RCTXR: f79f86a916325b346aa879e417ebcf27b95d93c5 + React-rendererconsistency: 0ca5004cb82d0a5550955dd3593cd2ebeda25457 + React-rendererdebug: b91a3027ff07c58c3306e029c1da7b3b3c0abd97 + React-rncore: 70e0b76634f90404805cd159595ce74900bdc80d + React-RuntimeApple: aabc75825a6e486d3d9523ee93fe9d83e14b13c6 + React-RuntimeCore: 4d6127a02c8200bfb49923733c2ec2240106d46d + React-runtimeexecutor: 90cca54336482cf43d7c2b3c80af3f4cef1d1e0e + React-RuntimeHermes: 3c5d14d1acdc9d17d62a048f11d9af115e0ac263 + React-runtimescheduler: c42bd8cc26171a3534a98d6fb19aec4761b2854f + React-timing: 211dd30779c09ed8a2ba9fd7a1343ad37a9c9e82 + React-utils: 76d8c01d580264f17d9f039da69afac43b774e36 + ReactCodegen: e0b48721f27c77ea8bf1b26038bee317efc219fc + ReactCommon: 245600a1b02f0987c92d108b9d727f128faa08fb + ReactCommon-Samples: b4ddc137d57d049c827f7a356b8df1bf39dd227b + ScreenshotManager: 4bd1cc50a26fe3225c48add3fd254f8e9cba38ca + SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 + Yoga: 961e7e2a9fad70b36e221e75b3e45637a33cbdca + +PODFILE CHECKSUM: ecf8d73b0aefca76e0e218d8845b105ea9282718 COCOAPODS: 1.14.3 diff --git a/packages/rn-tester/RNTester-visionOS/App.swift b/packages/rn-tester/RNTester-visionOS/App.swift index 8e28482981e8a6..83cd9daa9c2fb4 100644 --- a/packages/rn-tester/RNTester-visionOS/App.swift +++ b/packages/rn-tester/RNTester-visionOS/App.swift @@ -5,11 +5,27 @@ import React_RCTSwiftExtensions @main struct RNTesterApp: App { @UIApplicationDelegateAdaptor var delegate: AppDelegate + @Environment(\.reactContext) private var reactContext + @State private var immersionLevel: ImmersionStyle = .full var body: some Scene { RCTMainWindow(moduleName: "RNTesterApp") + .onOpenURL(perform: { url in + RCTLinkingManager.onOpenURL(url: url) + }) + + RCTWindow(id: "SecondWindow", sceneData: reactContext.getSceneData(id: "SecondWindow")) { rootView in + rootView.ornament(attachmentAnchor: .scene(.bottom)) { + VStack { + Button("Hey!") {} + } + .glassBackgroundEffect() + } + } + .defaultSize(CGSize(width: 400, height: 700)) + ImmersiveSpace(id: "TestImmersiveSpace") {} - .immersionStyle(selection: $immersionLevel, in: .mixed, .progressive, .full) + .immersionStyle(selection: $immersionLevel, in: .mixed, .progressive, .full) } } diff --git a/packages/rn-tester/RNTester-visionOS/Info.plist b/packages/rn-tester/RNTester-visionOS/Info.plist index 20f75e2afa73d1..a05d67cebe956c 100644 --- a/packages/rn-tester/RNTester-visionOS/Info.plist +++ b/packages/rn-tester/RNTester-visionOS/Info.plist @@ -2,6 +2,19 @@ + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLName + com.reactjs.ios + CFBundleURLSchemes + + rntester + + + UIApplicationSceneManifest UIApplicationPreferredDefaultSceneSessionRole diff --git a/packages/rn-tester/RNTester/AppDelegate.mm b/packages/rn-tester/RNTester/AppDelegate.mm index abb61d492ac554..eacc13101b2c61 100644 --- a/packages/rn-tester/RNTester/AppDelegate.mm +++ b/packages/rn-tester/RNTester/AppDelegate.mm @@ -107,7 +107,6 @@ - (void)application:(__unused UIApplication *)application [RCTPushNotificationManager didFailToRegisterForRemoteNotificationsWithError:error]; } -#if !TARGET_OS_VISION #pragma mark - UNUserNotificationCenterDelegate // Required for the remoteNotificationReceived and localNotificationReceived events @@ -137,7 +136,6 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center [RCTPushNotificationManager didReceiveNotification:notification]; completionHandler(); } -#endif #pragma mark - New Arch Enabled settings diff --git a/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj b/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj index 17056a64133616..4004e64498e0f2 100644 --- a/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj +++ b/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj @@ -98,7 +98,7 @@ 359825B9A5AE4A3F4AA612DD /* Pods-RNTesterUnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterUnitTests.debug.xcconfig"; path = "Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests.debug.xcconfig"; sourceTree = ""; }; 383889D923A7398900D06C3E /* RCTConvert_UIColorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTConvert_UIColorTests.m; sourceTree = ""; }; 3D2AFAF41D646CF80089D1A3 /* legacy_image@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "legacy_image@2x.png"; path = "RNTester/legacy_image@2x.png"; sourceTree = ""; }; - 51202427770AB438DEA21CE7 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = ../RNTester/PrivacyInfo.xcprivacy; sourceTree = ""; }; + 51202427770AB438DEA21CE7 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = ../RNTester/PrivacyInfo.xcprivacy; sourceTree = ""; }; 54DDA3DF154A732E76DCCEE8 /* Pods-RNTester-visionOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester-visionOS.release.xcconfig"; path = "Target Support Files/Pods-RNTester-visionOS/Pods-RNTester-visionOS.release.xcconfig"; sourceTree = ""; }; 5C60EB1B226440DB0018C04F /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = RNTester/AppDelegate.mm; sourceTree = ""; }; 63C6B5E1C2465D85E9BDB6E5 /* libPods-RNTesterIntegrationTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterIntegrationTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -117,7 +117,7 @@ 9B8542B8C590B51BD0588751 /* Pods-RNTester.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester.release.xcconfig"; path = "Target Support Files/Pods-RNTester/Pods-RNTester.release.xcconfig"; sourceTree = ""; }; A975CA6B2C05EADE0043F72A /* RCTNetworkTaskTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTNetworkTaskTests.m; sourceTree = ""; }; AC474BFB29BBD4A1002BDAED /* RNTester.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; name = RNTester.xctestplan; path = RNTester/RNTester.xctestplan; sourceTree = ""; }; - C1142D4D3F85531561B1F08E /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = RNTester/PrivacyInfo.xcprivacy; sourceTree = ""; }; + C1142D4D3F85531561B1F08E /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = RNTester/PrivacyInfo.xcprivacy; sourceTree = ""; }; CD10C7A4290BD4EB0033E1ED /* RCTEventEmitterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTEventEmitterTests.m; sourceTree = ""; }; D6942D0981036096211E5BDC /* libPods-RNTesterUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; E771AEEA22B44E3100EA1189 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = RNTester/Info.plist; sourceTree = ""; }; @@ -461,8 +461,8 @@ 763DC36F2B0F824200D2C0C5 /* Frameworks */, 763DC3702B0F824200D2C0C5 /* Resources */, 763DC38C2B10A42B00D2C0C5 /* Build JS Bundle */, - D88C968E3153313E61AE696C /* [CP] Embed Pods Frameworks */, 8634A0D0E14BF96B8A2F986B /* [CP] Copy Pods Resources */, + 953FE68EE569F573EC761880 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -801,29 +801,24 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester-visionOS/Pods-RNTester-visionOS-resources.sh\"\n"; showEnvVarsInLog = 0; }; - ABDE2A52ACD1B95E14790B5E /* [CP] Check Pods Manifest.lock */ = { + 953FE68EE569F573EC761880 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-RNTester-visionOS/Pods-RNTester-visionOS-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RNTester-checkManifestLockResult.txt", + "${PODS_ROOT}/Target Support Files/Pods-RNTester-visionOS/Pods-RNTester-visionOS-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester-visionOS/Pods-RNTester-visionOS-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - B7EB74515CDE78D98087DD53 /* [CP] Check Pods Manifest.lock */ = { + ABDE2A52ACD1B95E14790B5E /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -838,28 +833,33 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RNTesterIntegrationTests-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-RNTester-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - D88C968E3153313E61AE696C /* [CP] Embed Pods Frameworks */ = { + B7EB74515CDE78D98087DD53 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTester-visionOS/Pods-RNTester-visionOS-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTester-visionOS/Pods-RNTester-visionOS-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RNTesterIntegrationTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester-visionOS/Pods-RNTester-visionOS-frameworks.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; E446637427ECD101CAACE52B /* [CP] Copy Pods Resources */ = { @@ -907,7 +907,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - A975CA6C2C05EADF0043F72A /* RCTNetworkTaskTests.m in Sources */, E7DB20DF22B2BAA6005AC45F /* RCTImageLoaderTests.m in Sources */, E7DB20D222B2BAA6005AC45F /* RCTModuleInitNotificationRaceTests.m in Sources */, E7DB20D522B2BAA6005AC45F /* RCTPerformanceLoggerTests.m in Sources */, diff --git a/packages/rn-tester/js/RNTesterApp.ios.js b/packages/rn-tester/js/RNTesterApp.ios.js index 281ee25afd77a1..8ea87c26361438 100644 --- a/packages/rn-tester/js/RNTesterApp.ios.js +++ b/packages/rn-tester/js/RNTesterApp.ios.js @@ -24,6 +24,9 @@ AppRegistry.registerComponent('SetPropertiesExampleApp', () => AppRegistry.registerComponent('RootViewSizeFlexibilityExampleApp', () => require('./examples/RootViewSizeFlexibilityExample/RootViewSizeFlexibilityExampleApp'), ); +AppRegistry.registerComponent('SecondWindow', () => + require('./examples/SecondWindow/SecondWindow'), +); AppRegistry.registerComponent('RNTesterApp', () => RNTesterApp); // Register suitable examples for snapshot tests diff --git a/packages/rn-tester/js/examples/SecondWindow/SecondWindow.js b/packages/rn-tester/js/examples/SecondWindow/SecondWindow.js new file mode 100644 index 00000000000000..10f71a32dae917 --- /dev/null +++ b/packages/rn-tester/js/examples/SecondWindow/SecondWindow.js @@ -0,0 +1,52 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + * @flow + */ + +'use strict'; + +const {WindowManager} = require('@callstack/react-native-visionos'); +const React = require('react'); +const {Button, StyleSheet, Text, View} = require('react-native'); + +type Props = $ReadOnly<{| + title?: String, +|}>; + +const SecondWindow = ({title}: Props): React.Node => { + const [counter, setCounter] = React.useState(0); + return ( + + {title} + {counter} +