diff --git a/.circleci/configurations/jobs.yml b/.circleci/configurations/jobs.yml
index 3a1e0da816f2d7..9e71adf9d81e58 100644
--- a/.circleci/configurations/jobs.yml
+++ b/.circleci/configurations/jobs.yml
@@ -96,6 +96,8 @@ jobs:
- run:
name: "Run Tests: JavaScript Tests"
command: node ./scripts/run-ci-javascript-tests.js --maxWorkers 2
+ # - run_e2e:
+ # platform: js
# Optionally, run disabled tests
- when:
diff --git a/README.md b/README.md
index 4d8883c511c666..fe5b8e5e1b2103 100644
--- a/README.md
+++ b/README.md
@@ -1,147 +1,52 @@
Learn once, write anywhere:
- Build mobile apps with React.
+ Build spatial apps with React.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-React Native brings [**React**'s][r] declarative UI framework to iOS and Android. With React Native, you use native UI controls and have full access to the native platform.
-
-- **Declarative.** React makes it painless to create interactive UIs. Declarative views make your code more predictable and easier to debug.
-- **Component-Based.** Build encapsulated components that manage their state, then compose them to make complex UIs.
-- **Developer Velocity.** See local changes in seconds. Changes to JavaScript code can be live reloaded without rebuilding the native app.
-- **Portability.** Reuse code across iOS, Android, and [other platforms][p].
-
-React Native is developed and supported by many companies and individual core contributors. Find out more in our [ecosystem overview][e].
-
-[r]: https://react.dev/
-[p]: https://reactnative.dev/docs/out-of-tree-platforms
-[e]: https://github.com/facebook/react-native/blob/HEAD/ECOSYSTEM.md
-
-## Contents
-
-- [Requirements](#-requirements)
-- [Building your first React Native app](#-building-your-first-react-native-app)
-- [Documentation](#-documentation)
-- [Upgrading](#-upgrading)
-- [How to Contribute](#-how-to-contribute)
-- [Code of Conduct](#code-of-conduct)
-- [License](#-license)
-
-
-## 📋 Requirements
-
-React Native apps may target iOS 13.4 and Android 6.0 (API 23) or newer. You may use Windows, macOS, or Linux as your development operating system, though building and running iOS apps is limited to macOS. Tools like [Expo](https://expo.dev) can be used to work around this.
+React Native visionOS allows you to write visionOS with full support for platform SDK. This is a full fork of the main repository with changes needed to support visionOS.
-## 🎉 Building your first React Native app
+![Screenshot](https://github.com/callstack/react-native-visionos/assets/52801365/0fcd5e5f-628c-49ef-84ab-d1d4675a011a)
-Follow the [Getting Started guide](https://reactnative.dev/docs/getting-started). The recommended way to install React Native depends on your project. Here you can find short guides for the most common scenarios:
+## 🎉 Building your first spatial React Native app
+Follow the [Getting Started](https://callstack.github.io/react-native-visionos-docs/category/getting-started) guide. If you wish to get started quickly, you can utilize this command:
-- [Trying out React Native][hello-world]
-- [Creating a New Application][new-app]
-- [Adding React Native to an Existing Application][existing]
+```sh
+npx @callstack/react-native-visionos@latest init YourApp
+```
-[hello-world]: https://snack.expo.dev/@samples/hello-world
-[new-app]: https://reactnative.dev/docs/getting-started
-[existing]: https://reactnative.dev/docs/integration-with-existing-apps
## 📖 Documentation
-The full documentation for React Native can be found on our [website][docs].
-
-The React Native documentation discusses components, APIs, and topics that are specific to React Native. For further documentation on the React API that is shared between React Native and React DOM, refer to the [React documentation][r-docs].
-
-The source for the React Native documentation and website is hosted on a separate repo, [**@facebook/react-native-website**][repo-website].
-
-[docs]: https://reactnative.dev/docs/getting-started
-[r-docs]: https://react.dev/learn
-[repo-website]: https://github.com/facebook/react-native-website
-
-## 🚀 Upgrading
-
-Upgrading to new versions of React Native may give you access to more APIs, views, developer tools, and other goodies. See the [Upgrading Guide][u] for instructions.
-
-React Native releases are discussed [in this discussion repo](https://github.com/reactwg/react-native-releases/discussions).
-
-[u]: https://reactnative.dev/docs/upgrading
-[repo-releases]: https://github.com/react-native-community/react-native-releases
-
-## 👏 How to Contribute
-
-The main purpose of this repository is to continue evolving React Native core. We want to make contributing to this project as easy and transparent as possible, and we are grateful to the community for contributing bug fixes and improvements. Read below to learn how you can take part in improving React Native.
-
-### [Code of Conduct][code]
-
-Facebook has adopted a Code of Conduct that we expect project participants to adhere to.
-Please read the [full text][code] so that you can understand what actions will and will not be tolerated.
-
-[code]: https://code.fb.com/codeofconduct/
-
-### [Contributing Guide][contribute]
-
-Read our [**Contributing Guide**][contribute] to learn about our development process, how to propose bugfixes and improvements, and how to build and test your changes to React Native.
-
-[contribute]: https://reactnative.dev/docs/contributing
-
-### [Open Source Roadmap][roadmap]
-
-You can learn more about our vision for React Native in the [**Roadmap**][roadmap].
+The full documentation for React Native visionOS can be found on our [website](https://callstack.github.io/react-native-visionos-docs).
-[roadmap]: https://github.com/facebook/react-native/wiki/Roadmap
+The source for the React Native visionOS documentation and website is hosted on a separate repo, @callstack/react-native-visionos-docs.
-### Good First Issues
+## Contributing
-We have a list of [good first issues][gfi] that contain bugs which have a relatively limited scope. This is a great place to get started, gain experience, and get familiar with our contribution process.
+Prerequisites:
+- Download the latest Xcode (at least 15.2)
+- Install the latest version of CMake (at least v3.28.0)
-[gfi]: https://github.com/facebook/react-native/labels/good%20first%20issue
+Check out `rn-tester` [README.md](./packages/rn-tester/README.md) to build React Native from the source.
-### Discussions
+Remember to use `RNTester-visionOS` target
-Larger discussions and proposals are discussed in [**@react-native-community/discussions-and-proposals**][repo-meta].
+If `RNTester-visionOS` scheme is not showing up, click "New Scheme", which should be pre-populated with `RNTester-visionOS`. Build the app using Xcode.
-[repo-meta]: https://github.com/react-native-community/discussions-and-proposals
+## Release process
-## 📄 License
+We use a script called `oot-release.js` which automatically releases `visionos` packages and aligns versions of dependencies with React Native core.
-React Native is MIT licensed, as found in the [LICENSE][l] file.
+Usage:
-React Native documentation is Creative Commons licensed, as found in the [LICENSE-docs][ld] file.
+```sh
+node ./scripts/oot-release.js --new-version "" --react-native-version "" --one-time-password ""
+```
-[l]: https://github.com/facebook/react-native/blob/main/LICENSE
-[ld]: https://github.com/facebook/react-native/blob/main/LICENSE-docs
+To test releases and template we use [Verdaccio](https://verdaccio.org/).
diff --git a/jest.config.js b/jest.config.js
index f81a4049d9a5d2..9d3ca151f96dfc 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -40,6 +40,15 @@ module.exports = {
defaultPlatform: 'ios',
platforms: ['ios', 'android'],
},
+ moduleNameMapper: {
+ // These mappers allow out-of-tree platforms tests to seamlessly resolve RN imports
+ '^react-native/(.*)': '/packages/react-native/$1',
+ '^react-native$': '/packages/react-native/index.js',
+ // This module is internal to Meta and used by their custom React renderer.
+ // In tests, we can just use a mock.
+ '^ReactNativeInternalFeatureFlags$':
+ '/packages/react-native/jest/ReactNativeInternalFeatureFlagsMock.js',
+ },
moduleFileExtensions: ['fb.js'].concat(defaults.moduleFileExtensions),
modulePathIgnorePatterns: ['scripts/.*/__fixtures__/'],
unmockedModulePathPatterns: [
diff --git a/packages/out-of-tree-platforms/.gitignore b/packages/out-of-tree-platforms/.gitignore
new file mode 100644
index 00000000000000..ac0720f94136cd
--- /dev/null
+++ b/packages/out-of-tree-platforms/.gitignore
@@ -0,0 +1,2 @@
+# Build output
+/dist
\ No newline at end of file
diff --git a/packages/out-of-tree-platforms/README.md b/packages/out-of-tree-platforms/README.md
new file mode 100644
index 00000000000000..972663edaca00e
--- /dev/null
+++ b/packages/out-of-tree-platforms/README.md
@@ -0,0 +1,19 @@
+# @callstack/out-of-tree-platforms
+
+[![Version][version-badge]][package]
+
+Utilities for Out of Tree (OOT) platforms.
+
+## `getPlatformResolver`
+
+```js
+getPlatformResolver(options: ResolverConfig): CustomResolver
+```
+
+### options
+
+```js
+type ResolverConfig = {
+ platformImplementations: {[platform: string]: string},
+};
+```
diff --git a/packages/out-of-tree-platforms/index.js.flow b/packages/out-of-tree-platforms/index.js.flow
new file mode 100644
index 00000000000000..8420b1093fdb2f
--- /dev/null
+++ b/packages/out-of-tree-platforms/index.js.flow
@@ -0,0 +1 @@
+export * from './src';
diff --git a/packages/out-of-tree-platforms/package.json b/packages/out-of-tree-platforms/package.json
new file mode 100644
index 00000000000000..ee09627611fd41
--- /dev/null
+++ b/packages/out-of-tree-platforms/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "@callstack/out-of-tree-platforms",
+ "version": "0.75.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",
+ "bugs": "https://github.com/callstack/react-native-visionos/issues",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/callstack/react-native-visionos.git",
+ "directory": "packages/out-of-tree-platforms"
+ },
+ "license": "MIT",
+ "exports": {
+ ".": "./src/index.js",
+ "./package.json": "./package.json"
+ },
+ "files": [
+ "dist"
+ ],
+ "devDependencies": {
+ "metro-resolver": "^0.80.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+}
diff --git a/packages/out-of-tree-platforms/src/getPlatformResolver.js b/packages/out-of-tree-platforms/src/getPlatformResolver.js
new file mode 100644
index 00000000000000..70e3acde5c1d78
--- /dev/null
+++ b/packages/out-of-tree-platforms/src/getPlatformResolver.js
@@ -0,0 +1,43 @@
+/**
+ * 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.
+ *
+ * @flow
+ * @format
+ */
+
+import type {CustomResolver} from 'metro-resolver';
+
+type ResolverConfig = {
+ platformNameMap: {[platform: string]: string},
+};
+
+/**
+ * Creates a custom Metro resolver that maps platform extensions to package names.
+ * To be used in app's `metro.config.js` as `resolver.resolveRequest`.
+ */
+export const getPlatformResolver = (config: ResolverConfig): CustomResolver => {
+ return (context, moduleName, platform) => {
+ // `customResolverOptions` is populated through `?resolver.platformExtension` query params
+ // in the jsBundleURLForBundleRoot method of the react-native/React/Base/RCTBundleURLProvider.mm
+ const platformExtension = context.customResolverOptions?.platformExtension;
+ let modifiedModuleName = moduleName;
+ if (
+ typeof platformExtension === 'string' &&
+ config.platformNameMap?.[platformExtension]
+ ) {
+ const packageName = config.platformNameMap[platformExtension];
+ if (moduleName === 'react-native') {
+ modifiedModuleName = packageName;
+ } else if (moduleName.startsWith('react-native/')) {
+ modifiedModuleName = `${packageName}/${modifiedModuleName.slice(
+ 'react-native/'.length,
+ )}`;
+ }
+ }
+
+ return context.resolveRequest(context, modifiedModuleName, platform);
+ };
+};
diff --git a/packages/out-of-tree-platforms/src/index.js b/packages/out-of-tree-platforms/src/index.js
new file mode 100644
index 00000000000000..2244b1ce77d29e
--- /dev/null
+++ b/packages/out-of-tree-platforms/src/index.js
@@ -0,0 +1,5 @@
+if (!process.env.BUILD_EXCLUDE_BABEL_REGISTER) {
+ require('../../../scripts/build/babel-register').registerForMonorepo();
+}
+
+export * from './getPlatformResolver';
diff --git a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm
index 1748b07f17fd3f..c0f0a926126d0f 100644
--- a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm
+++ b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm
@@ -18,6 +18,7 @@
#import
#import "RCTAppDelegate+Protected.h"
#import "RCTAppSetupUtils.h"
+#import
#if RN_DISABLE_OSS_PLUGIN_HEADER
#import
@@ -48,10 +49,6 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
self.rootViewFactory = [self createRCTRootViewFactory];
- UIView *rootView = [self.rootViewFactory viewWithModuleName:self.moduleName
- initialProperties:self.initialProps
- launchOptions:launchOptions];
-
if (self.newArchEnabled || self.fabricEnabled) {
[RCTComponentViewFactory currentComponentViewFactory].thirdPartyFabricComponentsProvider = self;
}
diff --git a/packages/react-native/Libraries/Components/Keyboard/Keyboard.js b/packages/react-native/Libraries/Components/Keyboard/Keyboard.js
index 8aae204e97f328..fd23d472e95a57 100644
--- a/packages/react-native/Libraries/Components/Keyboard/Keyboard.js
+++ b/packages/react-native/Libraries/Components/Keyboard/Keyboard.js
@@ -15,6 +15,7 @@ import LayoutAnimation from '../../LayoutAnimation/LayoutAnimation';
import dismissKeyboard from '../../Utilities/dismissKeyboard';
import Platform from '../../Utilities/Platform';
import NativeKeyboardObserver from './NativeKeyboardObserver';
+import warnOnce from '../../Utilities/warnOnce';
export type KeyboardEventName = $Keys;
@@ -114,6 +115,10 @@ class Keyboard {
);
constructor() {
+ if (Platform.isVision) {
+ return;
+ }
+
this.addListener('keyboardDidShow', ev => {
this._currentlyShowing = ev;
});
@@ -151,6 +156,14 @@ class Keyboard {
listener: (...$ElementType) => mixed,
context?: mixed,
): EventSubscription {
+ if (Platform.isVision) {
+ warnOnce(
+ 'Keyboard-unavailable',
+ 'Keyboard API is not available on visionOS platform. The system displays the keyboard in a separate window, leaving the app’s window unaffected by the keyboard’s appearance and disappearance',
+ );
+ return {remove() {}};
+ }
+
return this._emitter.addListener(eventType, listener);
}
@@ -160,6 +173,10 @@ class Keyboard {
* @param {string} eventType The native event string listeners are watching which will be removed.
*/
removeAllListeners>(eventType: ?K): void {
+ if (Platform.isVision) {
+ return;
+ }
+
this._emitter.removeAllListeners(eventType);
}
diff --git a/packages/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js b/packages/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js
index e26d6771c47209..efea2b6683f40f 100644
--- a/packages/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js
+++ b/packages/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js
@@ -24,6 +24,7 @@ import AccessibilityInfo from '../AccessibilityInfo/AccessibilityInfo';
import View from '../View/View';
import Keyboard from './Keyboard';
import * as React from 'react';
+import warnOnce from '../../Utilities/warnOnce';
type Props = $ReadOnly<{|
...ViewProps,
@@ -176,6 +177,13 @@ class KeyboardAvoidingView extends React.Component {
componentDidMount(): void {
if (Platform.OS === 'ios') {
+ if (Platform.isVision) {
+ warnOnce(
+ 'KeyboardAvoidingView-unavailable',
+ 'KeyboardAvoidingView is not available on visionOS platform. The system displays the keyboard in a separate window, leaving the app’s window unaffected by the keyboard’s appearance and disappearance',
+ );
+ return;
+ }
this._subscriptions = [
Keyboard.addListener('keyboardWillChangeFrame', this._onKeyboardChange),
];
@@ -205,6 +213,16 @@ class KeyboardAvoidingView extends React.Component {
onLayout,
...props
} = this.props;
+
+ if (Platform.isVision) {
+ // KeyboardAvoidingView is not supported on VisionOS, so we return a simple View without the onLayout handler
+ return (
+
+ {children}
+
+ );
+ }
+
const bottomHeight = enabled === true ? this.state.bottom : 0;
switch (behavior) {
case 'height':
diff --git a/packages/react-native/Libraries/Components/Pressable/Pressable.js b/packages/react-native/Libraries/Components/Pressable/Pressable.js
index bd0d6a43a3a666..8b4bc667bdbf38 100644
--- a/packages/react-native/Libraries/Components/Pressable/Pressable.js
+++ b/packages/react-native/Libraries/Components/Pressable/Pressable.js
@@ -24,6 +24,7 @@ import type {
import {PressabilityDebugView} from '../../Pressability/PressabilityDebug';
import usePressability from '../../Pressability/usePressability';
import {type RectOrSize} from '../../StyleSheet/Rect';
+import StyleSheet from '../../StyleSheet/StyleSheet';
import useMergeRefs from '../../Utilities/useMergeRefs';
import View from '../View/View';
import useAndroidRippleForView, {
@@ -347,7 +348,10 @@ function Pressable(
{...restPropsWithDefaults}
{...eventHandlers}
ref={mergedRef}
- style={typeof style === 'function' ? style({pressed}) : style}
+ style={[
+ styles.pressable,
+ typeof style === 'function' ? style({pressed}) : style,
+ ]}
collapsable={false}>
{typeof children === 'function' ? children({pressed}) : children}
{__DEV__ ? : null}
@@ -355,6 +359,12 @@ function Pressable(
);
}
+const styles = StyleSheet.create({
+ pressable: {
+ cursor: 'pointer',
+ },
+});
+
function usePressState(forcePressed: boolean): [boolean, (boolean) => void] {
const [pressed, setPressed] = useState(false);
return [pressed || forcePressed, setPressed];
diff --git a/packages/react-native/Libraries/Components/Pressable/__tests__/__snapshots__/Pressable-test.js.snap b/packages/react-native/Libraries/Components/Pressable/__tests__/__snapshots__/Pressable-test.js.snap
index 307aaba80c6af8..9fddf3ccb102dc 100644
--- a/packages/react-native/Libraries/Components/Pressable/__tests__/__snapshots__/Pressable-test.js.snap
+++ b/packages/react-native/Libraries/Components/Pressable/__tests__/__snapshots__/Pressable-test.js.snap
@@ -31,6 +31,14 @@ exports[` should render as expected: should deep render when mocked
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
+ style={
+ Array [
+ Object {
+ "cursor": "pointer",
+ },
+ undefined,
+ ]
+ }
>
@@ -67,6 +75,14 @@ exports[` should render as expected: should deep render when not mo
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
+ style={
+ Array [
+ Object {
+ "cursor": "pointer",
+ },
+ undefined,
+ ]
+ }
>
@@ -103,6 +119,14 @@ exports[` should be disabled when disabled is true:
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
+ style={
+ Array [
+ Object {
+ "cursor": "pointer",
+ },
+ undefined,
+ ]
+ }
>
@@ -139,6 +163,14 @@ exports[` should be disabled when disabled is true:
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
+ style={
+ Array [
+ Object {
+ "cursor": "pointer",
+ },
+ undefined,
+ ]
+ }
>
@@ -175,6 +207,14 @@ exports[` should be disable
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
+ style={
+ Array [
+ Object {
+ "cursor": "pointer",
+ },
+ undefined,
+ ]
+ }
>
@@ -211,6 +251,14 @@ exports[` should be disable
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
+ style={
+ Array [
+ Object {
+ "cursor": "pointer",
+ },
+ undefined,
+ ]
+ }
>
@@ -247,6 +295,14 @@ exports[` shou
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
+ style={
+ Array [
+ Object {
+ "cursor": "pointer",
+ },
+ undefined,
+ ]
+ }
>
@@ -283,6 +339,14 @@ exports[` shou
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
+ style={
+ Array [
+ Object {
+ "cursor": "pointer",
+ },
+ undefined,
+ ]
+ }
>
@@ -319,6 +383,14 @@ exports[` sh
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
+ style={
+ Array [
+ Object {
+ "cursor": "pointer",
+ },
+ undefined,
+ ]
+ }
>
@@ -355,6 +427,14 @@ exports[` sh
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
+ style={
+ Array [
+ Object {
+ "cursor": "pointer",
+ },
+ undefined,
+ ]
+ }
>
diff --git a/packages/react-native/Libraries/Components/ScrollView/ScrollView.js b/packages/react-native/Libraries/Components/ScrollView/ScrollView.js
index dbe5bf1f218a68..ec18e56f3c336c 100644
--- a/packages/react-native/Libraries/Components/ScrollView/ScrollView.js
+++ b/packages/react-native/Libraries/Components/ScrollView/ScrollView.js
@@ -783,22 +783,24 @@ class ScrollView extends React.Component {
this._keyboardMetrics = Keyboard.metrics();
this._additionalScrollOffset = 0;
- this._subscriptionKeyboardWillShow = Keyboard.addListener(
- 'keyboardWillShow',
- this.scrollResponderKeyboardWillShow,
- );
- this._subscriptionKeyboardWillHide = Keyboard.addListener(
- 'keyboardWillHide',
- this.scrollResponderKeyboardWillHide,
- );
- this._subscriptionKeyboardDidShow = Keyboard.addListener(
- 'keyboardDidShow',
- this.scrollResponderKeyboardDidShow,
- );
- this._subscriptionKeyboardDidHide = Keyboard.addListener(
- 'keyboardDidHide',
- this.scrollResponderKeyboardDidHide,
- );
+ if (Platform.isVision) {
+ this._subscriptionKeyboardWillShow = Keyboard.addListener(
+ 'keyboardWillShow',
+ this.scrollResponderKeyboardWillShow,
+ );
+ this._subscriptionKeyboardWillHide = Keyboard.addListener(
+ 'keyboardWillHide',
+ this.scrollResponderKeyboardWillHide,
+ );
+ this._subscriptionKeyboardDidShow = Keyboard.addListener(
+ 'keyboardDidShow',
+ this.scrollResponderKeyboardDidShow,
+ );
+ this._subscriptionKeyboardDidHide = Keyboard.addListener(
+ 'keyboardDidHide',
+ this.scrollResponderKeyboardDidHide,
+ );
+ }
this._updateAnimatedNodeAttachment();
}
diff --git a/packages/react-native/Libraries/Components/StatusBar/StatusBar.js b/packages/react-native/Libraries/Components/StatusBar/StatusBar.js
index 20c2cf49d9fe69..a533c7d63acdbd 100644
--- a/packages/react-native/Libraries/Components/StatusBar/StatusBar.js
+++ b/packages/react-native/Libraries/Components/StatusBar/StatusBar.js
@@ -12,6 +12,7 @@ import type {ColorValue} from '../../StyleSheet/StyleSheet';
import processColor from '../../StyleSheet/processColor';
import Platform from '../../Utilities/Platform';
+import warnOnce from '../../Utilities/warnOnce';
import NativeStatusBarManagerAndroid from './NativeStatusBarManagerAndroid';
import NativeStatusBarManagerIOS from './NativeStatusBarManagerIOS';
import invariant from 'invariant';
@@ -373,6 +374,13 @@ class StatusBar extends React.Component {
_stackEntry = null;
componentDidMount() {
+ if (Platform.isVision) {
+ warnOnce(
+ 'StatusBar-unavailable',
+ 'StatusBar is not available on visionOS platform.',
+ );
+ return;
+ }
// Every time a StatusBar component is mounted, we push it's prop to a stack
// and always update the native status bar with the props from the top of then
// stack. This allows having multiple StatusBar components and the one that is
diff --git a/packages/react-native/Libraries/Components/TextInput/InputAccessoryView.js b/packages/react-native/Libraries/Components/TextInput/InputAccessoryView.js
index 89b438e54944ef..5250b0615f9d15 100644
--- a/packages/react-native/Libraries/Components/TextInput/InputAccessoryView.js
+++ b/packages/react-native/Libraries/Components/TextInput/InputAccessoryView.js
@@ -90,7 +90,7 @@ type Props = $ReadOnly<{|
const InputAccessoryView: React.AbstractComponent = (props: Props) => {
const {width} = useWindowDimensions();
- if (Platform.OS === 'ios') {
+ if (Platform.OS === 'ios' && !Platform.isVision) {
if (React.Children.count(props.children) === 0) {
return null;
}
diff --git a/packages/react-native/Libraries/Components/Touchable/TouchableHighlight.js b/packages/react-native/Libraries/Components/Touchable/TouchableHighlight.js
index 61e9f210110a1d..dcc133af3e8d6c 100644
--- a/packages/react-native/Libraries/Components/Touchable/TouchableHighlight.js
+++ b/packages/react-native/Libraries/Components/Touchable/TouchableHighlight.js
@@ -329,10 +329,13 @@ class TouchableHighlight extends React.Component {
accessibilityElementsHidden={
this.props['aria-hidden'] ?? this.props.accessibilityElementsHidden
}
- style={StyleSheet.compose(
- this.props.style,
- this.state.extraStyles?.underlay,
- )}
+ style={[
+ styles.touchable,
+ StyleSheet.compose(
+ this.props.style,
+ this.state.extraStyles?.underlay,
+ ),
+ ]}
onLayout={this.props.onLayout}
hitSlop={this.props.hitSlop}
hasTVPreferredFocus={this.props.hasTVPreferredFocus}
@@ -381,6 +384,12 @@ class TouchableHighlight extends React.Component {
}
}
+const styles = StyleSheet.create({
+ touchable: {
+ cursor: 'pointer',
+ },
+});
+
const Touchable: React.AbstractComponent<
$ReadOnly<$Diff|}>>,
React.ElementRef,
diff --git a/packages/react-native/Libraries/Components/Touchable/TouchableOpacity.js b/packages/react-native/Libraries/Components/Touchable/TouchableOpacity.js
index 14ca87aba403cd..1d75cafe5be266 100644
--- a/packages/react-native/Libraries/Components/Touchable/TouchableOpacity.js
+++ b/packages/react-native/Libraries/Components/Touchable/TouchableOpacity.js
@@ -18,6 +18,7 @@ import Pressability, {
} from '../../Pressability/Pressability';
import {PressabilityDebugView} from '../../Pressability/PressabilityDebug';
import flattenStyle from '../../StyleSheet/flattenStyle';
+import StyleSheet from '../../StyleSheet/StyleSheet';
import Platform from '../../Utilities/Platform';
import * as React from 'react';
@@ -275,7 +276,7 @@ class TouchableOpacity extends React.Component {
accessibilityElementsHidden={
this.props['aria-hidden'] ?? this.props.accessibilityElementsHidden
}
- style={[this.props.style, {opacity: this.state.anim}]}
+ style={[styles.touchable, this.props.style, {opacity: this.state.anim}]}
nativeID={this.props.id ?? this.props.nativeID}
testID={this.props.testID}
onLayout={this.props.onLayout}
@@ -326,6 +327,12 @@ class TouchableOpacity extends React.Component {
}
}
+const styles = StyleSheet.create({
+ touchable: {
+ cursor: 'pointer',
+ },
+});
+
const Touchable: React.AbstractComponent<
Props,
React.ElementRef,
diff --git a/packages/react-native/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableHighlight-test.js.snap b/packages/react-native/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableHighlight-test.js.snap
index 35c845e97493fc..f26560d45d738a 100644
--- a/packages/react-native/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableHighlight-test.js.snap
+++ b/packages/react-native/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableHighlight-test.js.snap
@@ -19,7 +19,14 @@ exports[`TouchableHighlight renders correctly 1`] = `
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
- style={Object {}}
+ style={
+ Array [
+ Object {
+ "cursor": "pointer",
+ },
+ Object {},
+ ]
+ }
>
Touchable
@@ -51,6 +58,14 @@ exports[`TouchableHighlight with disabled state should be disabled when disabled
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
+ style={
+ Array [
+ Object {
+ "cursor": "pointer",
+ },
+ undefined,
+ ]
+ }
>
@@ -80,6 +95,14 @@ exports[`TouchableHighlight with disabled state should be disabled when disabled
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
+ style={
+ Array [
+ Object {
+ "cursor": "pointer",
+ },
+ undefined,
+ ]
+ }
>
@@ -109,6 +132,14 @@ exports[`TouchableHighlight with disabled state should disable button when acces
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
+ style={
+ Array [
+ Object {
+ "cursor": "pointer",
+ },
+ undefined,
+ ]
+ }
>
@@ -139,6 +170,14 @@ exports[`TouchableHighlight with disabled state should keep accessibilityState w
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
+ style={
+ Array [
+ Object {
+ "cursor": "pointer",
+ },
+ undefined,
+ ]
+ }
>
@@ -168,6 +207,14 @@ exports[`TouchableHighlight with disabled state should overwrite accessibilitySt
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
+ style={
+ Array [
+ Object {
+ "cursor": "pointer",
+ },
+ undefined,
+ ]
+ }
>
diff --git a/packages/react-native/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableOpacity-test.js.snap b/packages/react-native/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableOpacity-test.js.snap
index 17f2e7f6f764e0..ca634909ca5afc 100644
--- a/packages/react-native/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableOpacity-test.js.snap
+++ b/packages/react-native/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableOpacity-test.js.snap
@@ -31,6 +31,7 @@ exports[`TouchableOpacity renders correctly 1`] = `
onStartShouldSetResponder={[Function]}
style={
Object {
+ "cursor": "pointer",
"opacity": 1,
}
}
@@ -72,6 +73,7 @@ exports[`TouchableOpacity renders in disabled state when a disabled prop is pass
onStartShouldSetResponder={[Function]}
style={
Object {
+ "cursor": "pointer",
"opacity": 1,
}
}
@@ -113,6 +115,7 @@ exports[`TouchableOpacity renders in disabled state when a key disabled in acces
onStartShouldSetResponder={[Function]}
style={
Object {
+ "cursor": "pointer",
"opacity": 1,
}
}
diff --git a/packages/react-native/Libraries/Components/__tests__/__snapshots__/Button-test.js.snap b/packages/react-native/Libraries/Components/__tests__/__snapshots__/Button-test.js.snap
index 5b4294e0e8c850..a3efb80e477bfc 100644
--- a/packages/react-native/Libraries/Components/__tests__/__snapshots__/Button-test.js.snap
+++ b/packages/react-native/Libraries/Components/__tests__/__snapshots__/Button-test.js.snap
@@ -32,6 +32,7 @@ exports[` should be disabled and it should set accessibilityState to d
onStartShouldSetResponder={[Function]}
style={
Object {
+ "cursor": "pointer",
"opacity": 1,
}
}
@@ -98,6 +99,7 @@ exports[` should be disabled when disabled is empty and accessibilityS
onStartShouldSetResponder={[Function]}
style={
Object {
+ "cursor": "pointer",
"opacity": 1,
}
}
@@ -164,6 +166,7 @@ exports[` should be disabled when disabled={true} and accessibilitySta
onStartShouldSetResponder={[Function]}
style={
Object {
+ "cursor": "pointer",
"opacity": 1,
}
}
@@ -231,6 +234,7 @@ exports[` should be set importantForAccessibility={no-hide-descendants
onStartShouldSetResponder={[Function]}
style={
Object {
+ "cursor": "pointer",
"opacity": 1,
}
}
@@ -293,6 +297,7 @@ exports[` should be set importantForAccessibility={no-hide-descendants
onStartShouldSetResponder={[Function]}
style={
Object {
+ "cursor": "pointer",
"opacity": 1,
}
}
@@ -354,6 +359,7 @@ exports[` should not be disabled when disabled={false} and accessibili
onStartShouldSetResponder={[Function]}
style={
Object {
+ "cursor": "pointer",
"opacity": 1,
}
}
@@ -416,6 +422,7 @@ exports[` should not be disabled when disabled={false} and accessibili
onStartShouldSetResponder={[Function]}
style={
Object {
+ "cursor": "pointer",
"opacity": 1,
}
}
@@ -478,6 +485,7 @@ exports[` should overwrite accessibilityState with value of disabled p
onStartShouldSetResponder={[Function]}
style={
Object {
+ "cursor": "pointer",
"opacity": 1,
}
}
@@ -544,6 +552,7 @@ exports[` should render as expected 1`] = `
onStartShouldSetResponder={[Function]}
style={
Object {
+ "cursor": "pointer",
"opacity": 1,
}
}
diff --git a/packages/react-native/Libraries/Image/React-RCTImage.podspec b/packages/react-native/Libraries/Image/React-RCTImage.podspec
index 5aacf0d7999c32..8f77a54b2372b5 100644
--- a/packages/react-native/Libraries/Image/React-RCTImage.podspec
+++ b/packages/react-native/Libraries/Image/React-RCTImage.podspec
@@ -45,7 +45,7 @@ Pod::Spec.new do |s|
"CLANG_CXX_LANGUAGE_STANDARD" => "c++20",
"HEADER_SEARCH_PATHS" => header_search_paths.join(' ')
}
- s.framework = ["Accelerate", "UIKit"]
+ s.framework = ["Accelerate", "UIKit", "QuartzCore", "ImageIO", "CoreGraphics"]
s.dependency "RCT-Folly", folly_version
s.dependency "RCTTypeSafety"
diff --git a/packages/react-native/Libraries/LinkingIOS/React-RCTLinking.podspec b/packages/react-native/Libraries/LinkingIOS/React-RCTLinking.podspec
index eff125c9615056..bc7316170eae11 100644
--- a/packages/react-native/Libraries/LinkingIOS/React-RCTLinking.podspec
+++ b/packages/react-native/Libraries/LinkingIOS/React-RCTLinking.podspec
@@ -45,6 +45,8 @@ Pod::Spec.new do |s|
"HEADER_SEARCH_PATHS" => header_search_paths.join(' ')
}
+ 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 c9f32c9eea7e36..be3896746a4abc 100644
--- a/packages/react-native/Libraries/NativeAnimation/React-RCTAnimation.podspec
+++ b/packages/react-native/Libraries/NativeAnimation/React-RCTAnimation.podspec
@@ -44,6 +44,8 @@ Pod::Spec.new do |s|
"HEADER_SEARCH_PATHS" => header_search_paths.join(" ")
}
+ s.framework = ["UIKit", "QuartzCore"]
+
s.dependency "RCT-Folly", folly_version
s.dependency "RCTTypeSafety"
s.dependency "React-jsi"
diff --git a/packages/react-native/Libraries/NewAppScreen/components/Header.js b/packages/react-native/Libraries/NewAppScreen/components/Header.js
index 5e44c81a37b4a0..149e464311e629 100644
--- a/packages/react-native/Libraries/NewAppScreen/components/Header.js
+++ b/packages/react-native/Libraries/NewAppScreen/components/Header.js
@@ -42,7 +42,7 @@ const Header = (): Node => {
]}>
Welcome to
{'\n'}
- React Native
+ React Native visionOS
);
@@ -56,7 +56,7 @@ const styles = StyleSheet.create({
},
logo: {
opacity: 0.2,
- overflow: 'visible',
+ overflow: 'hidden',
resizeMode: 'cover',
/*
* These negative margins allow the image to be offset similarly across screen sizes and component sizes.
@@ -65,7 +65,6 @@ const styles = StyleSheet.create({
* source image's size.
*/
marginLeft: -128,
- marginBottom: -192,
},
text: {
fontSize: 40,
diff --git a/packages/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm b/packages/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm
index 86f11c42f60cc4..9ad375fa299621 100644
--- a/packages/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm
+++ b/packages/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm
@@ -510,6 +510,7 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification
: (RCTPromiseResolveBlock)resolve reject
: (__unused RCTPromiseRejectBlock)reject)
{
+#if !TARGET_OS_VISION
// The user actioned a local or remote notification to launch the app. Notification is represented by UNNotification.
// Set this property in the implementation of
// userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler.
@@ -529,6 +530,7 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification
}
resolve((id)kCFNull);
+#endif
}
RCT_EXPORT_METHOD(getScheduledLocalNotifications : (RCTResponseSenderBlock)callback)
diff --git a/packages/react-native/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec b/packages/react-native/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec
index 7a82e20d911a68..6f274ca83d4dea 100644
--- a/packages/react-native/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec
+++ b/packages/react-native/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec
@@ -44,7 +44,7 @@ Pod::Spec.new do |s|
"CLANG_CXX_LANGUAGE_STANDARD" => "c++20",
"HEADER_SEARCH_PATHS" => header_search_paths.join(' ')
}
- s.framework = "UserNotifications"
+ s.framework = ["UIKit", "UserNotifications"]
s.dependency "RCTTypeSafety"
s.dependency "React-Core/RCTPushNotificationHeaders"
diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTMainWindow.swift b/packages/react-native/Libraries/SwiftExtensions/RCTMainWindow.swift
new file mode 100644
index 00000000000000..1bf0bca5901b63
--- /dev/null
+++ b/packages/react-native/Libraries/SwiftExtensions/RCTMainWindow.swift
@@ -0,0 +1,34 @@
+import SwiftUI
+
+/**
+ This SwiftUI struct returns main React Native scene. It should be used only once as it conains setup code.
+
+ Example:
+ ```swift
+ @main
+ struct YourApp: App {
+ @UIApplicationDelegateAdaptor var delegate: AppDelegate
+
+ var body: some Scene {
+ RCTMainWindow(moduleName: "YourApp")
+ }
+ }
+ ```
+
+ Note: If you want to create additional windows in your app, create a new `WindowGroup {}` and pass it a `RCTRootViewRepresentable`.
+*/
+public struct RCTMainWindow: Scene {
+ var moduleName: String
+ var initialProps: RCTRootViewRepresentable.InitialPropsType
+
+ public init(moduleName: String, initialProps: RCTRootViewRepresentable.InitialPropsType = nil) {
+ self.moduleName = moduleName
+ self.initialProps = initialProps
+ }
+
+ public var body: some Scene {
+ WindowGroup {
+ RCTRootViewRepresentable(moduleName: moduleName, initialProps: initialProps)
+ }
+ }
+}
diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTReactViewController.h b/packages/react-native/Libraries/SwiftExtensions/RCTReactViewController.h
new file mode 100644
index 00000000000000..13de19c37cf0e2
--- /dev/null
+++ b/packages/react-native/Libraries/SwiftExtensions/RCTReactViewController.h
@@ -0,0 +1,16 @@
+#import
+
+/**
+ A `UIViewController` responsible for embeding `RCTRootView` inside. Uses Factory pattern to retrive new view instances.
+
+ Note: Used to in `RCTRootViewRepresentable` to display React views.
+ */
+@interface RCTReactViewController : UIViewController
+
+@property (nonatomic, strong, nonnull) NSString *moduleName;
+@property (nonatomic, strong, nullable) NSDictionary *initialProps;
+
+- (instancetype _Nonnull)initWithModuleName:(NSString *_Nonnull)moduleName
+ initProps:(NSDictionary *_Nullable)initProps;
+
+@end
diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTReactViewController.m b/packages/react-native/Libraries/SwiftExtensions/RCTReactViewController.m
new file mode 100644
index 00000000000000..e051b6a1aabe48
--- /dev/null
+++ b/packages/react-native/Libraries/SwiftExtensions/RCTReactViewController.m
@@ -0,0 +1,71 @@
+#import "RCTReactViewController.h"
+#import
+#import
+#import
+#import
+
+@protocol RCTRootViewFactoryProtocol
+
+- (UIView *)viewWithModuleName:(NSString *)moduleName initialProperties:(NSDictionary*)initialProperties launchOptions:(NSDictionary*)launchOptions;
+
+@end
+
+@protocol RCTFocusedWindowProtocol
+
+@property (nonatomic, nullable) UIWindow *lastFocusedWindow;
+
+@end
+
+@implementation RCTReactViewController
+
+- (instancetype)initWithModuleName:(NSString *)moduleName initProps:(NSDictionary *)initProps {
+ if (self = [super init]) {
+ _moduleName = moduleName;
+ _initialProps = initProps;
+ }
+ return self;
+}
+
+- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator {
+ [[NSNotificationCenter defaultCenter] postNotificationName:RCTWindowFrameDidChangeNotification object:self];
+}
+
+- (void)loadView {
+ RCTAppDelegate * appDelegate = (RCTAppDelegate *)[UIApplication sharedApplication].delegate;
+ if ([appDelegate respondsToSelector:@selector(rootViewFactory)]) {
+ self.view = [appDelegate.rootViewFactory viewWithModuleName:_moduleName initialProperties:_initialProps];
+ } else {
+ [NSException raise:@"UIApplicationDelegate:viewWithModuleName:initialProperties:launchOptions: not implemented"
+ format:@"Make sure you subclass RCTAppDelegate"];
+ }
+}
+
+- (void)viewDidLoad {
+ UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGesture:)];
+ [self.view addGestureRecognizer:tapGesture];
+}
+
+- (void)tapGesture:(UITapGestureRecognizer*)recognizer {
+ id appDelegate = (id)RCTSharedApplication().delegate;
+
+ if (![appDelegate respondsToSelector:@selector(lastFocusedWindow)]) {
+ return;
+ }
+
+ UIWindow *targetWindow = recognizer.view.window;
+ if (targetWindow != appDelegate.lastFocusedWindow) {
+ appDelegate.lastFocusedWindow = targetWindow;
+ }
+}
+
+- (void)updateProps:(NSDictionary *)newProps {
+ RCTRootView *rootView = (RCTRootView *)self.view;
+ if (rootView.appProperties == newProps) {
+ return;
+ }
+
+ if (newProps != nil && ![rootView.appProperties isEqualToDictionary:newProps]) {
+ [rootView setAppProperties:newProps];
+ }
+}
+@end
diff --git a/packages/react-native/Libraries/SwiftExtensions/RCTRootViewRepresentable.swift b/packages/react-native/Libraries/SwiftExtensions/RCTRootViewRepresentable.swift
new file mode 100644
index 00000000000000..6a89db9d08e2d7
--- /dev/null
+++ b/packages/react-native/Libraries/SwiftExtensions/RCTRootViewRepresentable.swift
@@ -0,0 +1,32 @@
+import SwiftUI
+
+/**
+ SwiftUI view enclosing `RCTReactViewController`. Its main purpose is to display React Native views inside of SwiftUI lifecycle.
+
+ Use it create new windows in your app:
+ Example:
+ ```swift
+ WindowGroup {
+ RCTRootViewRepresentable(moduleName: "YourAppName")
+ }
+ ```
+*/
+public struct RCTRootViewRepresentable: UIViewControllerRepresentable {
+ public typealias InitialPropsType = [AnyHashable: Any]?
+
+ var moduleName: String
+ var initialProps: InitialPropsType
+
+ public init(moduleName: String, initialProps: InitialPropsType = nil) {
+ self.moduleName = moduleName
+ self.initialProps = initialProps
+ }
+
+ public func makeUIViewController(context: Context) -> UIViewController {
+ RCTReactViewController(moduleName: moduleName, initProps: initialProps)
+ }
+
+ public func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
+ // noop
+ }
+}
diff --git a/packages/react-native/Libraries/SwiftExtensions/React-RCTSwiftExtensions.podspec b/packages/react-native/Libraries/SwiftExtensions/React-RCTSwiftExtensions.podspec
new file mode 100644
index 00000000000000..d5dbdafe37ff6d
--- /dev/null
+++ b/packages/react-native/Libraries/SwiftExtensions/React-RCTSwiftExtensions.podspec
@@ -0,0 +1,27 @@
+require "json"
+
+package = JSON.parse(File.read(File.join(__dir__, "..", "..", "package.json")))
+version = package['version']
+
+source = { :git => 'https://github.com/facebook/react-native.git' }
+if version == '1000.0.0'
+ # This is an unpublished version, use the latest commit hash of the react-native repo, which we’re presumably in.
+ source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1")
+else
+ source[:tag] = "v#{version}"
+end
+
+Pod::Spec.new do |s|
+ s.name = "React-RCTSwiftExtensions"
+ s.version = version
+ s.summary = "A library for easier React Native integration with SwiftUI."
+ s.homepage = "https://reactnative.dev/"
+ s.license = package["license"]
+ s.author = "Callstack"
+ s.platforms = min_supported_versions
+ s.source = source
+ s.source_files = "*.{swift,h,m}"
+ s.frameworks = ["UIKit", "SwiftUI"]
+
+ s.dependency "React-Core"
+end
diff --git a/packages/react-native/Libraries/Text/Text/RCTTextView.mm b/packages/react-native/Libraries/Text/Text/RCTTextView.mm
index 47632aa885cdb3..c68f1d706a6be4 100644
--- a/packages/react-native/Libraries/Text/Text/RCTTextView.mm
+++ b/packages/react-native/Libraries/Text/Text/RCTTextView.mm
@@ -247,6 +247,7 @@ - (void)handleLongPress:(UILongPressGestureRecognizer *)gesture
[_editMenuInteraction presentEditMenuWithConfiguration:config];
}
} else {
+#if !TARGET_OS_VISION
UIMenuController *menuController = [UIMenuController sharedMenuController];
if (menuController.isMenuVisible) {
@@ -254,6 +255,7 @@ - (void)handleLongPress:(UILongPressGestureRecognizer *)gesture
}
[menuController showMenuFromView:self rect:self.bounds];
+#endif
}
}
diff --git a/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm b/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm
index 72cf885c37e824..3415828656739e 100644
--- a/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm
+++ b/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.mm
@@ -632,6 +632,7 @@ - (void)didSetProps:(NSArray *)changedProps
- (void)setCustomInputAccessoryViewWithNativeID:(NSString *)nativeID
{
+#if !TARGET_OS_VISION
__weak RCTBaseTextInputView *weakSelf = self;
[_bridge.uiManager rootViewForReactTag:self.reactTag
withCompletion:^(UIView *rootView) {
@@ -646,6 +647,7 @@ - (void)setCustomInputAccessoryViewWithNativeID:(NSString *)nativeID
}
}
}];
+#endif
}
- (NSString *)returnKeyTypeToString:(UIReturnKeyType)returnKeyType
@@ -695,6 +697,7 @@ - (void)initializeReturnKeyType
- (void)setDefaultInputAccessoryView
{
+#if !TARGET_OS_VISION
UIView *textInputView = self.backedTextInputView;
UIKeyboardType keyboardType = textInputView.keyboardType;
@@ -733,6 +736,7 @@ - (void)setDefaultInputAccessoryView
textInputView.inputAccessoryView = nil;
}
[self reloadInputViewsIfNecessary];
+#endif
}
- (void)reloadInputViewsIfNecessary
diff --git a/packages/react-native/Libraries/WindowManager/React-RCTWindowManager.podspec b/packages/react-native/Libraries/WindowManager/React-RCTWindowManager.podspec
new file mode 100644
index 00000000000000..10dffa748f7e15
--- /dev/null
+++ b/packages/react-native/Libraries/WindowManager/React-RCTWindowManager.podspec
@@ -0,0 +1,51 @@
+require "json"
+
+package = JSON.parse(File.read(File.join(__dir__, "..", "..", "package.json")))
+version = package['version']
+
+source = { :git => 'https://github.com/facebook/react-native.git' }
+if version == '1000.0.0'
+ # This is an unpublished version, use the latest commit hash of the react-native repo, which we’re presumably in.
+ source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1")
+else
+ source[:tag] = "v#{version}"
+end
+
+folly_config = get_folly_config()
+folly_compiler_flags = folly_config[:compiler_flags]
+folly_version = folly_config[:version]
+
+header_search_paths = [
+ "\"$(PODS_ROOT)/RCT-Folly\"",
+ "\"${PODS_ROOT}/Headers/Public/React_Codegen/react/renderer/components\"",
+]
+
+Pod::Spec.new do |s|
+ s.name = "React-RCTWindowManager"
+ s.version = version
+ s.summary = "Window manager module for React Native."
+ s.homepage = "https://callstack.github.io/react-native-visionos-docs"
+ s.documentation_url = "https://callstack.github.io/react-native-visionos-docs/api/windowmanager"
+ s.license = package["license"]
+ s.author = "Callstack"
+ s.platforms = min_supported_versions
+ s.compiler_flags = folly_compiler_flags + ' -Wno-nullability-completeness'
+ s.source = source
+ s.source_files = "*.{m,mm,swift}"
+ s.preserve_paths = "package.json", "LICENSE", "LICENSE-docs"
+ s.header_dir = "RCTWindowManager"
+ s.pod_target_xcconfig = {
+ "USE_HEADERMAP" => "YES",
+ "CLANG_CXX_LANGUAGE_STANDARD" => "c++20",
+ "HEADER_SEARCH_PATHS" => header_search_paths.join(' ')
+ }
+
+ s.dependency "RCT-Folly", folly_version
+ s.dependency "RCTTypeSafety"
+ s.dependency "React-jsi"
+ s.dependency "React-Core/RCTWindowManagerHeaders"
+
+ add_dependency(s, "ReactCodegen", :additional_framework_paths => ["build/generated/ios"])
+ add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"])
+ add_dependency(s, "React-NativeModulesApple", :additional_framework_paths => ["build/generated/ios"])
+end
diff --git a/packages/react-native/Libraries/XR/React-RCTXR.podspec b/packages/react-native/Libraries/XR/React-RCTXR.podspec
new file mode 100644
index 00000000000000..23fc4ba7c2f481
--- /dev/null
+++ b/packages/react-native/Libraries/XR/React-RCTXR.podspec
@@ -0,0 +1,51 @@
+require "json"
+
+package = JSON.parse(File.read(File.join(__dir__, "..", "..", "package.json")))
+version = package['version']
+
+source = { :git => 'https://github.com/facebook/react-native.git' }
+if version == '1000.0.0'
+ # This is an unpublished version, use the latest commit hash of the react-native repo, which we’re presumably in.
+ source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1")
+else
+ source[:tag] = "v#{version}"
+end
+
+folly_config = get_folly_config()
+folly_compiler_flags = folly_config[:compiler_flags]
+folly_version = folly_config[:version]
+
+header_search_paths = [
+ "\"$(PODS_ROOT)/RCT-Folly\"",
+ "\"${PODS_ROOT}/Headers/Public/React_Codegen/react/renderer/components\"",
+]
+
+Pod::Spec.new do |s|
+ s.name = "React-RCTXR"
+ s.version = version
+ s.summary = "XR module for React Native."
+ s.homepage = "https://callstack.github.io/react-native-visionos-docs/"
+ s.documentation_url = "https://callstack.github.io/react-native-visionos-docs/api/XR"
+ s.license = package["license"]
+ s.author = "Callstack"
+ s.platforms = min_supported_versions
+ s.compiler_flags = folly_compiler_flags + ' -Wno-nullability-completeness'
+ s.source = source
+ s.source_files = "*.{m,mm,swift}"
+ s.preserve_paths = "package.json", "LICENSE", "LICENSE-docs"
+ s.header_dir = "RCTXR"
+ s.pod_target_xcconfig = {
+ "USE_HEADERMAP" => "YES",
+ "CLANG_CXX_LANGUAGE_STANDARD" => "c++20",
+ "HEADER_SEARCH_PATHS" => header_search_paths.join(' ')
+ }
+
+ s.dependency "RCT-Folly", folly_version
+ s.dependency "RCTTypeSafety"
+ s.dependency "React-jsi"
+ s.dependency "React-Core/RCTXRHeaders"
+
+ add_dependency(s, "ReactCodegen", :additional_framework_paths => ["build/generated/ios"])
+ add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"])
+ add_dependency(s, "React-NativeModulesApple", :additional_framework_paths => ["build/generated/ios"])
+end
diff --git a/packages/react-native/React-Core.podspec b/packages/react-native/React-Core.podspec
index 45ddb79f5c79cb..a47cdc7226de05 100644
--- a/packages/react-native/React-Core.podspec
+++ b/packages/react-native/React-Core.podspec
@@ -19,7 +19,7 @@ end
folly_config = get_folly_config()
folly_compiler_flags = folly_config[:compiler_flags]
folly_version = folly_config[:version]
-socket_rocket_version = '0.7.0'
+socket_rocket_version = '0.7.0.1'
boost_compiler_flags = '-Wno-documentation'
use_hermes = ENV['USE_HERMES'] == nil || ENV['USE_HERMES'] == '1'
diff --git a/packages/react-native/React/Base/RCTBundleURLProvider.mm b/packages/react-native/React/Base/RCTBundleURLProvider.mm
index 8c32440fc7f741..fd9531ffd0033d 100644
--- a/packages/react-native/React/Base/RCTBundleURLProvider.mm
+++ b/packages/react-native/React/Base/RCTBundleURLProvider.mm
@@ -276,6 +276,9 @@ + (NSURL *)jsBundleURLForBundleRoot:(NSString *)bundleRoot
BOOL lazy = enableDev;
NSArray *queryItems = @[
[[NSURLQueryItem alloc] initWithName:@"platform" value:RCTPlatformName],
+#if TARGET_OS_VISION
+ [[NSURLQueryItem alloc] initWithName:@"resolver.platformExtension" value:RCTPlatformExtension],
+#endif
[[NSURLQueryItem alloc] initWithName:@"dev" value:enableDev ? @"true" : @"false"],
[[NSURLQueryItem alloc] initWithName:@"lazy" value:lazy ? @"true" : @"false"],
[[NSURLQueryItem alloc] initWithName:@"minify" value:enableMinification ? @"true" : @"false"],
diff --git a/packages/react-native/React/Base/RCTConstants.h b/packages/react-native/React/Base/RCTConstants.h
index 289e8a090334a5..9c69969916375d 100644
--- a/packages/react-native/React/Base/RCTConstants.h
+++ b/packages/react-native/React/Base/RCTConstants.h
@@ -8,6 +8,9 @@
#import
RCT_EXTERN NSString *const RCTPlatformName;
+#if TARGET_OS_VISION
+RCT_EXTERN NSString *const RCTPlatformExtension;
+#endif
RCT_EXTERN NSString *const RCTUserInterfaceStyleDidChangeNotification;
RCT_EXTERN NSString *const RCTUserInterfaceStyleDidChangeNotificationTraitCollectionKey;
diff --git a/packages/react-native/React/Base/RCTConstants.m b/packages/react-native/React/Base/RCTConstants.m
index 70e94ca6b65e03..b6b6acd412c05d 100644
--- a/packages/react-native/React/Base/RCTConstants.m
+++ b/packages/react-native/React/Base/RCTConstants.m
@@ -8,6 +8,9 @@
#import "RCTConstants.h"
NSString *const RCTPlatformName = @"ios";
+#if TARGET_OS_VISION
+NSString *const RCTPlatformExtension = @"visionos";
+#endif
NSString *const RCTUserInterfaceStyleDidChangeNotification = @"RCTUserInterfaceStyleDidChangeNotification";
NSString *const RCTUserInterfaceStyleDidChangeNotificationTraitCollectionKey = @"traitCollection";
diff --git a/packages/react-native/React/Base/RCTConvert.mm b/packages/react-native/React/Base/RCTConvert.mm
index c4b15a1df20b52..97b9d98b6efecb 100644
--- a/packages/react-native/React/Base/RCTConvert.mm
+++ b/packages/react-native/React/Base/RCTConvert.mm
@@ -550,8 +550,13 @@ + (UIKeyboardType)UIKeyboardType:(id)json RCT_DYNAMIC
(@{
@"default" : @(UIBarStyleDefault),
@"black" : @(UIBarStyleBlack),
+#if TARGET_OS_VISION
+ @"blackOpaque" : @(UIBarStyleBlack),
+ @"blackTranslucent" : @(UIBarStyleBlack),
+#else
@"blackOpaque" : @(UIBarStyleBlackOpaque),
@"blackTranslucent" : @(UIBarStyleBlackTranslucent),
+#endif
}),
UIBarStyleDefault,
integerValue)
diff --git a/packages/react-native/React/Base/RCTKeyCommands.m b/packages/react-native/React/Base/RCTKeyCommands.m
index 19ef5b1f0d461a..013d7de38914f4 100644
--- a/packages/react-native/React/Base/RCTKeyCommands.m
+++ b/packages/react-native/React/Base/RCTKeyCommands.m
@@ -127,8 +127,11 @@ - (void)handleKeyUIEventSwizzle:(UIEvent *)event
if ([event respondsToSelector:@selector(_isKeyDown)]) {
isKeyDown = [event _isKeyDown];
}
-
+#if !TARGET_OS_VISION
BOOL interactionEnabled = !RCTSharedApplication().isIgnoringInteractionEvents;
+#else
+ BOOL interactionEnabled = true;
+#endif
BOOL hasFirstResponder = NO;
if (isKeyDown && modifiedInput.length > 0 && interactionEnabled) {
UIResponder *firstResponder = nil;
diff --git a/packages/react-native/React/Base/RCTUtils.m b/packages/react-native/React/Base/RCTUtils.m
index 190c06aab0098c..40d4b4e4c87c73 100644
--- a/packages/react-native/React/Base/RCTUtils.m
+++ b/packages/react-native/React/Base/RCTUtils.m
@@ -361,9 +361,14 @@ CGSize RCTScreenSize(void)
static CGSize size;
static dispatch_once_t onceToken;
+
dispatch_once(&onceToken, ^{
RCTUnsafeExecuteOnMainQueueSync(^{
+#if TARGET_OS_VISION
+ size = RCTKeyWindow().bounds.size;
+#else
size = [UIScreen mainScreen].bounds.size;
+#endif
});
});
diff --git a/packages/react-native/React/CoreModules/RCTAlertController.mm b/packages/react-native/React/CoreModules/RCTAlertController.mm
index b47ce0adefa06f..1e3f8da53350b4 100644
--- a/packages/react-native/React/CoreModules/RCTAlertController.mm
+++ b/packages/react-native/React/CoreModules/RCTAlertController.mm
@@ -9,6 +9,20 @@
#import
+#if TARGET_OS_VISION
+@interface TransparentViewController : UIViewController
+
+@end
+
+@implementation TransparentViewController
+
+- (UIContainerBackgroundStyle)preferredContainerBackgroundStyle {
+ return UIContainerBackgroundStyleHidden;
+}
+
+@end
+#endif
+
@interface RCTAlertController ()
@property (nonatomic, strong) UIWindow *alertWindow;
@@ -23,7 +37,11 @@ - (UIWindow *)alertWindow
_alertWindow = [[UIWindow alloc] initWithWindowScene:RCTKeyWindow().windowScene];
if (_alertWindow) {
+#if TARGET_OS_VISION
+ _alertWindow.rootViewController = [TransparentViewController new];
+#else
_alertWindow.rootViewController = [UIViewController new];
+#endif
_alertWindow.windowLevel = UIWindowLevelAlert + 1;
}
}
diff --git a/packages/react-native/React/CoreModules/RCTAppearance.mm b/packages/react-native/React/CoreModules/RCTAppearance.mm
index 457a1d8b966d90..561be636f6ed8c 100644
--- a/packages/react-native/React/CoreModules/RCTAppearance.mm
+++ b/packages/react-native/React/CoreModules/RCTAppearance.mm
@@ -72,7 +72,9 @@ void RCTUseKeyWindowForSystemStyle(BOOL useMainScreen)
UIUserInterfaceStyle systemStyle = sUseKeyWindowForSystemStyle ? RCTKeyWindow().traitCollection.userInterfaceStyle
: traitCollection.userInterfaceStyle;
- return appearances[@(systemStyle)] ?: RCTAppearanceColorSchemeLight;
+
+ // Fallback to dark mode on visionOS
+ return appearances[@(systemStyle)] ?: RCTAppearanceColorSchemeDark;
}
@interface RCTAppearance ()
diff --git a/packages/react-native/React/CoreModules/RCTDevLoadingView.mm b/packages/react-native/React/CoreModules/RCTDevLoadingView.mm
index 12736cd5297f18..9e15a4ebd43c55 100644
--- a/packages/react-native/React/CoreModules/RCTDevLoadingView.mm
+++ b/packages/react-native/React/CoreModules/RCTDevLoadingView.mm
@@ -119,8 +119,15 @@ - (void)showMessage:(NSString *)message color:(UIColor *)color backgroundColor:(
CGFloat windowWidth = window.bounds.size.width;
self->_window = [[UIWindow alloc] initWithWindowScene:window.windowScene];
+#if TARGET_OS_VISION
+ self->_window.frame = CGRectMake(0, 0, windowWidth, window.safeAreaInsets.top + 30);
+ self->_label =
+ [[UILabel alloc] initWithFrame:CGRectMake(0, window.safeAreaInsets.top + 5, windowWidth, 20)];
+#else
self->_window.frame = CGRectMake(0, 0, windowWidth, window.safeAreaInsets.top + 10);
self->_label = [[UILabel alloc] initWithFrame:CGRectMake(0, window.safeAreaInsets.top - 10, windowWidth, 20)];
+#endif
+
[self->_window addSubview:self->_label];
self->_window.windowLevel = UIWindowLevelStatusBar + 1;
@@ -139,6 +146,7 @@ - (void)showMessage:(NSString *)message color:(UIColor *)color backgroundColor:(
});
[self hideBannerAfter:15.0];
+
}
RCT_EXPORT_METHOD(showMessage
diff --git a/packages/react-native/React/CoreModules/RCTDevMenu.mm b/packages/react-native/React/CoreModules/RCTDevMenu.mm
index 2f57d4b0b46a3d..f3c5ca675a8e51 100644
--- a/packages/react-native/React/CoreModules/RCTDevMenu.mm
+++ b/packages/react-native/React/CoreModules/RCTDevMenu.mm
@@ -424,9 +424,15 @@ - (RCTDevMenuAlertActionHandler)alertActionHandlerForDevItem:(RCTDevMenuItem *__
{
return ^(__unused UIAlertAction *action) {
if (item) {
+#if TARGET_OS_VISION
+ /// Execute this handler after the action sheet is dismissed to properly retrieve window when using SwiftUI entry point.
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0), dispatch_get_main_queue(), ^{
+ [item callHandler];
+ });
+#else
[item callHandler];
+#endif
}
-
self->_actionSheet = nil;
};
}
diff --git a/packages/react-native/React/CoreModules/RCTDeviceInfo.mm b/packages/react-native/React/CoreModules/RCTDeviceInfo.mm
index 573c0c320a0c6e..94bc7e55d0f7e6 100644
--- a/packages/react-native/React/CoreModules/RCTDeviceInfo.mm
+++ b/packages/react-native/React/CoreModules/RCTDeviceInfo.mm
@@ -51,9 +51,16 @@ - (void)initialize
selector:@selector(didReceiveNewContentSizeMultiplier)
name:RCTAccessibilityManagerDidUpdateMultiplierNotification
object:[_moduleRegistry moduleForName:"AccessibilityManager"]];
+
+#if !TARGET_OS_VISION
_currentInterfaceOrientation = [RCTSharedApplication() statusBarOrientation];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(interfaceOrientationDidChange)
+ name:UIApplicationDidChangeStatusBarOrientationNotification
+ object:nil];
+
_currentInterfaceDimensions = [self _exportedDimensions];
[[NSNotificationCenter defaultCenter] addObserver:self
@@ -100,7 +107,11 @@ - (void)_cleanupObservers
[[NSNotificationCenter defaultCenter] removeObserver:self
name:RCTAccessibilityManagerDidUpdateMultiplierNotification
object:[_moduleRegistry moduleForName:"AccessibilityManager"]];
-
+#if !TARGET_OS_VISION
+ [[NSNotificationCenter defaultCenter] removeObserver:self
+ name:UIApplicationDidChangeStatusBarOrientationNotification
+ object:nil];
+#endif
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:RCTUserInterfaceStyleDidChangeNotification object:nil];
@@ -115,15 +126,16 @@ - (void)_cleanupObservers
static BOOL RCTIsIPhoneNotched()
{
static BOOL isIPhoneNotched = NO;
- static dispatch_once_t onceToken;
+#if !TARGET_OS_VISION
+ static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- RCTAssertMainQueue();
-
- // 20pt is the top safeArea value in non-notched devices
- isIPhoneNotched = RCTSharedApplication().keyWindow.safeAreaInsets.top > 20;
- });
+ dispatch_once(&onceToken, ^{
+ RCTAssertMainQueue();
+ // 20pt is the top safeArea value in non-notched devices
+ isIPhoneNotched = RCTSharedApplication().keyWindow.safeAreaInsets.top > 20;
+ });
+#endif
return isIPhoneNotched;
}
@@ -206,6 +218,7 @@ - (void)interfaceOrientationDidChange
- (void)_interfaceOrientationDidChange
{
+#if !TARGET_OS_VISION
UIApplication *application = RCTSharedApplication();
UIInterfaceOrientation nextOrientation = [application statusBarOrientation];
@@ -235,6 +248,7 @@ - (void)_interfaceOrientationDidChange
_isFullscreen = isRunningInFullScreen;
#pragma clang diagnostic pop
}
+#endif
}
- (void)interfaceFrameDidChange
diff --git a/packages/react-native/React/CoreModules/RCTKeyboardObserver.mm b/packages/react-native/React/CoreModules/RCTKeyboardObserver.mm
index ce483ddceb95fc..0774d1f9a81ef7 100644
--- a/packages/react-native/React/CoreModules/RCTKeyboardObserver.mm
+++ b/packages/react-native/React/CoreModules/RCTKeyboardObserver.mm
@@ -23,6 +23,7 @@ @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]
@@ -35,6 +36,7 @@ - (void)startObserving
ADD_KEYBOARD_HANDLER(UIKeyboardDidChangeFrameNotification, keyboardDidChangeFrame);
#undef ADD_KEYBOARD_HANDLER
+#endif
}
- (NSArray *)supportedEvents
@@ -51,9 +53,12 @@ - (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.
@@ -72,6 +77,7 @@ -(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/CoreModules/RCTPerfMonitor.mm b/packages/react-native/React/CoreModules/RCTPerfMonitor.mm
index 023a5311db2e53..c028d95ef8e3e2 100644
--- a/packages/react-native/React/CoreModules/RCTPerfMonitor.mm
+++ b/packages/react-native/React/CoreModules/RCTPerfMonitor.mm
@@ -171,7 +171,8 @@ - (UIPanGestureRecognizer *)gestureRecognizer
- (UIView *)container
{
if (!_container) {
- CGSize statusBarSize = RCTSharedApplication().statusBarFrame.size;
+ CGSize statusBarSize = RCTUIStatusBarManager().statusBarFrame.size;
+
CGFloat statusBarHeight = statusBarSize.height;
_container = [[UIView alloc] initWithFrame:CGRectMake(10, statusBarHeight, 180, RCTPerfMonitorBarHeight)];
_container.layer.borderWidth = 2;
diff --git a/packages/react-native/React/CoreModules/RCTStatusBarManager.mm b/packages/react-native/React/CoreModules/RCTStatusBarManager.mm
index 015a91098e95cd..ab5b1e94d03088 100644
--- a/packages/react-native/React/CoreModules/RCTStatusBarManager.mm
+++ b/packages/react-native/React/CoreModules/RCTStatusBarManager.mm
@@ -79,6 +79,7 @@ + (BOOL)requiresMainQueueSetup
- (void)startObserving
{
+#if !TARGET_OS_VISION
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self
selector:@selector(applicationDidChangeStatusBarFrame:)
@@ -88,15 +89,19 @@ - (void)startObserving
selector:@selector(applicationWillChangeStatusBarFrame:)
name:UIApplicationWillChangeStatusBarFrameNotification
object:nil];
+#endif
}
- (void)stopObserving
{
+#if !TARGET_OS_VISION
[[NSNotificationCenter defaultCenter] removeObserver:self];
+#endif
}
- (void)emitEvent:(NSString *)eventName forNotification:(NSNotification *)notification
{
+#if !TARGET_OS_VISION
CGRect frame = [notification.userInfo[UIApplicationStatusBarFrameUserInfoKey] CGRectValue];
NSDictionary *event = @{
@"frame" : @{
@@ -107,6 +112,7 @@ - (void)emitEvent:(NSString *)eventName forNotification:(NSNotification *)notifi
},
};
[self sendEventWithName:eventName body:event];
+#endif
}
- (void)applicationDidChangeStatusBarFrame:(NSNotification *)notification
@@ -122,12 +128,13 @@ - (void)applicationWillChangeStatusBarFrame:(NSNotification *)notification
RCT_EXPORT_METHOD(getHeight : (RCTResponseSenderBlock)callback)
{
callback(@[ @{
- @"height" : @(RCTSharedApplication().statusBarFrame.size.height),
+ @"height" : @(RCTUIStatusBarManager().statusBarFrame.size),
} ]);
}
RCT_EXPORT_METHOD(setStyle : (NSString *)style animated : (BOOL)animated)
{
+#if !TARGET_OS_VISION
dispatch_async(dispatch_get_main_queue(), ^{
UIStatusBarStyle statusBarStyle = [RCTConvert UIStatusBarStyle:style];
if (RCTViewControllerBasedStatusBarAppearance()) {
@@ -136,14 +143,16 @@ - (void)applicationWillChangeStatusBarFrame:(NSNotification *)notification
} else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- [RCTSharedApplication() setStatusBarStyle:statusBarStyle animated:animated];
- }
+ [RCTSharedApplication() setStatusBarStyle:statusBarStyle animated:animated];
+ }
#pragma clang diagnostic pop
});
+#endif
}
RCT_EXPORT_METHOD(setHidden : (BOOL)hidden withAnimation : (NSString *)withAnimation)
{
+#if !TARGET_OS_VISION
dispatch_async(dispatch_get_main_queue(), ^{
UIStatusBarAnimation animation = [RCTConvert UIStatusBarAnimation:withAnimation];
if (RCTViewControllerBasedStatusBarAppearance()) {
@@ -152,17 +161,18 @@ - (void)applicationWillChangeStatusBarFrame:(NSNotification *)notification
} else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- [RCTSharedApplication() setStatusBarHidden:hidden withAnimation:animation];
+ [RCTSharedApplication() setStatusBarHidden:hidden withAnimation:animation];
#pragma clang diagnostic pop
}
});
+#endif
}
RCT_EXPORT_METHOD(setNetworkActivityIndicatorVisible : (BOOL)visible)
{
- dispatch_async(dispatch_get_main_queue(), ^{
+#if !TARGET_OS_VISION
RCTSharedApplication().networkActivityIndicatorVisible = visible;
- });
+#endif
}
- (facebook::react::ModuleConstants)getConstants
diff --git a/packages/react-native/React/CoreModules/React-CoreModules.podspec b/packages/react-native/React/CoreModules/React-CoreModules.podspec
index f29771e5c3eb2b..8af78493b73898 100644
--- a/packages/react-native/React/CoreModules/React-CoreModules.podspec
+++ b/packages/react-native/React/CoreModules/React-CoreModules.podspec
@@ -19,7 +19,7 @@ end
folly_config = get_folly_config()
folly_compiler_flags = folly_config[:compiler_flags]
folly_version = folly_config[:version]
-socket_rocket_version = '0.7.0'
+socket_rocket_version = '0.7.0.1'
header_search_paths = [
"\"$(PODS_ROOT)/boost\"",
diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/InputAccessory/RCTInputAccessoryComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/InputAccessory/RCTInputAccessoryComponentView.mm
index f152dabf3b9f4a..8dd2ba120b148b 100644
--- a/packages/react-native/React/Fabric/Mounting/ComponentViews/InputAccessory/RCTInputAccessoryComponentView.mm
+++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/InputAccessory/RCTInputAccessoryComponentView.mm
@@ -66,7 +66,9 @@ - (void)didMoveToWindow
if (self.window && !_textInput) {
if (self.nativeId) {
_textInput = RCTFindTextInputWithNativeId(self.window, self.nativeId);
+#if !TARGET_OS_VISION
_textInput.inputAccessoryView = _contentView;
+#endif
} else {
_textInput = RCTFindTextInputWithNativeId(_contentView, nil);
}
@@ -82,10 +84,12 @@ - (BOOL)canBecomeFirstResponder
return true;
}
+#if !TARGET_OS_VISION
- (UIView *)inputAccessoryView
{
return _contentView;
}
+#endif
#pragma mark - RCTComponentViewProtocol
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 ff8810cba4001d..7ceeb3e3f33ae9 100644
--- a/packages/react-native/React/Fabric/Mounting/ComponentViews/Modal/RCTFabricModalHostViewController.mm
+++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/Modal/RCTFabricModalHostViewController.mm
@@ -61,8 +61,13 @@ - (BOOL)prefersStatusBarHidden
#if RCT_DEV
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
+#if !TARGET_OS_VISION
UIInterfaceOrientationMask appSupportedOrientationsMask =
[RCTSharedApplication() supportedInterfaceOrientationsForWindow:[RCTSharedApplication() keyWindow]];
+#else
+ UIInterfaceOrientationMask appSupportedOrientationsMask = UIInterfaceOrientationMaskPortrait;
+#endif
+
if (!(_supportedInterfaceOrientations & appSupportedOrientationsMask)) {
RCTLogError(
@"Modal was presented with 0x%x orientations mask but the application only supports 0x%x."
diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm
index 98cf04959323cd..85a398dc535e4d 100644
--- a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm
+++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm
@@ -28,6 +28,7 @@
static const CGFloat kClippingLeeway = 44.0;
+#if !TARGET_OS_VISION
static UIScrollViewKeyboardDismissMode RCTUIKeyboardDismissModeFromProps(const ScrollViewProps &props)
{
switch (props.keyboardDismissMode) {
@@ -39,6 +40,7 @@ static UIScrollViewKeyboardDismissMode RCTUIKeyboardDismissModeFromProps(const S
return UIScrollViewKeyboardDismissModeInteractive;
}
}
+#endif
static UIScrollViewIndicatorStyle RCTUIScrollViewIndicatorStyleFromProps(const ScrollViewProps &props)
{
@@ -299,9 +301,11 @@ - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &
MAP_SCROLL_VIEW_PROP(disableIntervalMomentum);
MAP_SCROLL_VIEW_PROP(snapToInterval);
+#if !TARGET_OS_VISION
if (oldScrollViewProps.keyboardDismissMode != newScrollViewProps.keyboardDismissMode) {
scrollView.keyboardDismissMode = RCTUIKeyboardDismissModeFromProps(newScrollViewProps);
}
+#endif
[super updateProps:props oldProps:oldProps];
}
diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm
index d2f90b4afad8c7..a5b0bec72942c5 100644
--- a/packages/react-native/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm
+++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm
@@ -271,6 +271,7 @@ - (void)handleLongPress:(UILongPressGestureRecognizer *)gesture
[_editMenuInteraction presentEditMenuWithConfiguration:config];
}
} else {
+#if !TARGET_OS_VISION
UIMenuController *menuController = [UIMenuController sharedMenuController];
if (menuController.isMenuVisible) {
@@ -278,6 +279,7 @@ - (void)handleLongPress:(UILongPressGestureRecognizer *)gesture
}
[menuController showMenuFromView:self rect:self.bounds];
+#endif
}
}
diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm
index 51914b7448e837..dab1ce450cb815 100644
--- a/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm
+++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm
@@ -515,6 +515,7 @@ - (void)initializeReturnKeyType
- (void)setDefaultInputAccessoryView
{
+#if !TARGET_OS_VISION
// InputAccessoryView component sets the inputAccessoryView when inputAccessoryViewID exists
if (_backedTextInputView.inputAccessoryViewID) {
if (_backedTextInputView.isFirstResponder) {
@@ -559,6 +560,7 @@ - (void)setDefaultInputAccessoryView
if (_backedTextInputView.isFirstResponder) {
[_backedTextInputView reloadInputViews];
}
+#endif
}
- (void)handleInputAccessoryDoneButton
diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputUtils.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputUtils.mm
index d4b91c921b1114..3bc3f3a298e47f 100644
--- a/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputUtils.mm
+++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputUtils.mm
@@ -26,7 +26,9 @@ void RCTCopyBackedTextInput(
toTextInput.placeholder = fromTextInput.placeholder;
toTextInput.placeholderColor = fromTextInput.placeholderColor;
toTextInput.textContainerInset = fromTextInput.textContainerInset;
+#if !TARGET_OS_VISION
toTextInput.inputAccessoryView = fromTextInput.inputAccessoryView;
+#endif
toTextInput.textInputDelegate = fromTextInput.textInputDelegate;
toTextInput.placeholderColor = fromTextInput.placeholderColor;
toTextInput.defaultTextAttributes = fromTextInput.defaultTextAttributes;
diff --git a/packages/react-native/React/Fabric/RCTSurfacePointerHandler.mm b/packages/react-native/React/Fabric/RCTSurfacePointerHandler.mm
index 78dec24a9bd3db..5af98fb1b2ad7d 100644
--- a/packages/react-native/React/Fabric/RCTSurfacePointerHandler.mm
+++ b/packages/react-native/React/Fabric/RCTSurfacePointerHandler.mm
@@ -286,9 +286,15 @@ static PointerEvent CreatePointerEventFromActivePointer(
if (eventType == RCTPointerEventTypeCancel) {
event.clientPoint = RCTPointFromCGPoint(CGPointZero);
+#if TARGET_OS_VISION
+ event.screenPoint =
+ RCTPointFromCGPoint([rootComponentView convertPoint:CGPointZero
+ toCoordinateSpace:rootComponentView.window.coordinateSpace]);
+#else
event.screenPoint =
RCTPointFromCGPoint([rootComponentView convertPoint:CGPointZero
toCoordinateSpace:rootComponentView.window.screen.coordinateSpace]);
+#endif
event.offsetPoint = RCTPointFromCGPoint([rootComponentView convertPoint:CGPointZero
toView:activePointer.componentView]);
} else {
@@ -329,7 +335,6 @@ static PointerEvent CreatePointerEventFromActivePointer(
event.tangentialPressure = 0.0;
event.twist = 0;
event.isPrimary = activePointer.isPrimary;
-
return event;
}
@@ -374,8 +379,13 @@ static void UpdateActivePointerWithUITouch(
activePointer.componentView = FindClosestFabricManagedTouchableView(hitTestedView);
activePointer.clientPoint = [uiTouch locationInView:rootComponentView];
+#if TARGET_OS_VISION
+ activePointer.screenPoint = [rootComponentView convertPoint:activePointer.clientPoint
+ toCoordinateSpace:rootComponentView.window.coordinateSpace];
+#else
activePointer.screenPoint = [rootComponentView convertPoint:activePointer.clientPoint
toCoordinateSpace:rootComponentView.window.screen.coordinateSpace];
+#endif
activePointer.offsetPoint = [uiTouch locationInView:activePointer.componentView];
activePointer.timestamp = uiTouch.timestamp;
@@ -742,9 +752,13 @@ - (void)hovering:(UIHoverGestureRecognizer *)recognizer
{
UIView *listenerView = recognizer.view;
CGPoint clientLocation = [recognizer locationInView:listenerView];
+#if TARGET_OS_VISION
+ CGPoint screenLocation = [listenerView convertPoint:clientLocation
+ toCoordinateSpace:listenerView.window.coordinateSpace];
+#else
CGPoint screenLocation = [listenerView convertPoint:clientLocation
toCoordinateSpace:listenerView.window.screen.coordinateSpace];
-
+#endif
UIView *targetView = [listenerView hitTest:clientLocation withEvent:nil];
targetView = FindClosestFabricManagedTouchableView(targetView);
diff --git a/packages/react-native/React/Fabric/RCTSurfaceTouchHandler.mm b/packages/react-native/React/Fabric/RCTSurfaceTouchHandler.mm
index a793251fc622c3..59feea710f2cec 100644
--- a/packages/react-native/React/Fabric/RCTSurfaceTouchHandler.mm
+++ b/packages/react-native/React/Fabric/RCTSurfaceTouchHandler.mm
@@ -56,8 +56,13 @@ static void UpdateActiveTouchWithUITouch(
{
CGPoint offsetPoint = [uiTouch locationInView:activeTouch.componentView];
CGPoint pagePoint = [uiTouch locationInView:rootComponentView];
+#if TARGET_OS_VISION
+ CGPoint screenPoint = [rootComponentView convertPoint:pagePoint
+ toCoordinateSpace:rootComponentView.window.coordinateSpace];
+#else
CGPoint screenPoint = [rootComponentView convertPoint:pagePoint
toCoordinateSpace:rootComponentView.window.screen.coordinateSpace];
+#endif
pagePoint = CGPointMake(pagePoint.x + rootViewOriginOffset.x, pagePoint.y + rootViewOriginOffset.y);
activeTouch.touch.offsetPoint = RCTPointFromCGPoint(offsetPoint);
diff --git a/packages/react-native/React/Modules/RCTUIManager.m b/packages/react-native/React/Modules/RCTUIManager.m
index 31c12fd22789bb..fd21eeed0210e3 100644
--- a/packages/react-native/React/Modules/RCTUIManager.m
+++ b/packages/react-native/React/Modules/RCTUIManager.m
@@ -196,10 +196,12 @@ - (void)setBridge:(RCTBridge *)bridge
name:@"RCTAccessibilityManagerDidUpdateMultiplierNotification"
object:a11yManager];
});
+#if !TARGET_OS_VISION
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(namedOrientationDidChange)
name:UIDeviceOrientationDidChangeNotification
object:nil];
+#endif
[RCTLayoutAnimation initializeStatics];
}
@@ -267,16 +269,17 @@ - (void)didReceiveNewContentSizeMultiplier
- (void)namedOrientationDidChange
{
+#if !TARGET_OS_VISION
NSDictionary *orientationEvent = deviceOrientationEventBody([UIDevice currentDevice].orientation);
if (!orientationEvent) {
return;
}
-
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[[_moduleRegistry moduleForName:"EventDispatcher"] sendDeviceEventWithName:@"namedOrientationDidChange"
body:orientationEvent];
#pragma clang diagnostic pop
+#endif
}
- (dispatch_queue_t)methodQueue
diff --git a/packages/react-native/React/UIUtils/RCTUIUtils.m b/packages/react-native/React/UIUtils/RCTUIUtils.m
index b0e655fb4c544a..e986af9d2643dd 100644
--- a/packages/react-native/React/UIUtils/RCTUIUtils.m
+++ b/packages/react-native/React/UIUtils/RCTUIUtils.m
@@ -11,18 +11,26 @@
RCTDimensions RCTGetDimensions(CGFloat fontScale)
{
+#if !TARGET_OS_VISION
UIScreen *mainScreen = UIScreen.mainScreen;
CGSize screenSize = mainScreen.bounds.size;
-
+#endif
+
UIView *mainWindow = RCTKeyWindow();
+ CGFloat screenScale = [UITraitCollection currentTraitCollection].displayScale;
+
+#if TARGET_OS_VISION
+ CGSize windowSize = mainWindow.bounds.size;
+ CGSize screenSize = mainWindow.bounds.size;
+#else
// We fallback to screen size if a key window is not found.
CGSize windowSize = mainWindow ? mainWindow.bounds.size : screenSize;
-
+#endif
RCTDimensions result;
typeof(result.screen) dimsScreen = {
- .width = screenSize.width, .height = screenSize.height, .scale = mainScreen.scale, .fontScale = fontScale};
+ .width = screenSize.width, .height = screenSize.height, .scale = screenScale, .fontScale = fontScale};
typeof(result.window) dimsWindow = {
- .width = windowSize.width, .height = windowSize.height, .scale = mainScreen.scale, .fontScale = fontScale};
+ .width = windowSize.width, .height = windowSize.height, .scale = screenScale, .fontScale = fontScale};
result.screen = dimsScreen;
result.window = dimsWindow;
diff --git a/packages/react-native/React/Views/RCTModalHostView.m b/packages/react-native/React/Views/RCTModalHostView.m
index dfde4ae47ab137..f9b0c2c39e2eba 100644
--- a/packages/react-native/React/Views/RCTModalHostView.m
+++ b/packages/react-native/React/Views/RCTModalHostView.m
@@ -75,8 +75,11 @@ - (void)notifyForOrientationChange
if (!_onOrientationChange) {
return;
}
-
+#if !TARGET_OS_VISION
UIInterfaceOrientation currentOrientation = [RCTSharedApplication() statusBarOrientation];
+#else
+ UIInterfaceOrientation currentOrientation = UIInterfaceOrientationUnknown;
+#endif
if (currentOrientation == _lastKnownOrientation) {
return;
}
diff --git a/packages/react-native/React/Views/RCTModalHostViewController.m b/packages/react-native/React/Views/RCTModalHostViewController.m
index 50075ffd4847c3..03d443f4776f15 100644
--- a/packages/react-native/React/Views/RCTModalHostViewController.m
+++ b/packages/react-native/React/Views/RCTModalHostViewController.m
@@ -23,10 +23,11 @@ - (instancetype)init
}
self.modalInPresentation = YES;
-
+#if !TARGET_OS_VISION
_preferredStatusBarStyle = [RCTUIStatusBarManager() statusBarStyle];
_preferredStatusBarHidden = [RCTUIStatusBarManager() isStatusBarHidden];
-
+#endif
+
return self;
}
@@ -53,8 +54,12 @@ - (BOOL)prefersStatusBarHidden
#if RCT_DEV
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
+#if !TARGET_OS_VISION
UIInterfaceOrientationMask appSupportedOrientationsMask =
[RCTSharedApplication() supportedInterfaceOrientationsForWindow:[RCTSharedApplication() keyWindow]];
+#else
+ UIInterfaceOrientationMask appSupportedOrientationsMask = UIInterfaceOrientationMaskPortrait;
+#endif
if (!(_supportedInterfaceOrientations & appSupportedOrientationsMask)) {
RCTLogError(
@"Modal was presented with 0x%x orientations mask but the application only supports 0x%x."
diff --git a/packages/react-native/React/Views/RCTViewManager.h b/packages/react-native/React/Views/RCTViewManager.h
index 1676e69f2aca86..9cde0f096d513d 100644
--- a/packages/react-native/React/Views/RCTViewManager.h
+++ b/packages/react-native/React/Views/RCTViewManager.h
@@ -79,6 +79,25 @@ typedef void (^RCTViewManagerUIBlock)(RCTUIManager *uiManager, NSDictionary
#import
+#if !TARGET_OS_VISION
+
@interface RCTConvert (UIScrollView)
+ (UIScrollViewKeyboardDismissMode)UIScrollViewKeyboardDismissMode:(id)json;
@end
+#endif
+
@interface RCTScrollViewManager : RCTViewManager
@end
diff --git a/packages/react-native/React/Views/ScrollView/RCTScrollViewManager.m b/packages/react-native/React/Views/ScrollView/RCTScrollViewManager.m
index cd1e7eb016ab8d..87fc36624dfe56 100644
--- a/packages/react-native/React/Views/ScrollView/RCTScrollViewManager.m
+++ b/packages/react-native/React/Views/ScrollView/RCTScrollViewManager.m
@@ -14,6 +14,7 @@
@implementation RCTConvert (UIScrollView)
+#if !TARGET_OS_VISION
RCT_ENUM_CONVERTER(
UIScrollViewKeyboardDismissMode,
(@{
@@ -25,6 +26,7 @@ @implementation RCTConvert (UIScrollView)
}),
UIScrollViewKeyboardDismissModeNone,
integerValue)
+#endif
RCT_ENUM_CONVERTER(
UIScrollViewIndicatorStyle,
@@ -49,6 +51,7 @@ @implementation RCTConvert (UIScrollView)
@end
+
@implementation RCTScrollViewManager
RCT_EXPORT_MODULE()
@@ -71,7 +74,7 @@ - (UIView *)view
RCT_EXPORT_VIEW_PROPERTY(endDraggingSensitivityMultiplier, CGFloat)
RCT_EXPORT_VIEW_PROPERTY(directionalLockEnabled, BOOL)
RCT_EXPORT_VIEW_PROPERTY(indicatorStyle, UIScrollViewIndicatorStyle)
-RCT_EXPORT_VIEW_PROPERTY(keyboardDismissMode, UIScrollViewKeyboardDismissMode)
+RCT_EXPORT_NOT_VISIONOS_VIEW_PROPERTY(keyboardDismissMode, UIScrollViewKeyboardDismissMode)
RCT_EXPORT_VIEW_PROPERTY(maximumZoomScale, CGFloat)
RCT_EXPORT_VIEW_PROPERTY(minimumZoomScale, CGFloat)
RCT_EXPORT_VIEW_PROPERTY(scrollEnabled, BOOL)
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
new file mode 100644
index 00000000000000..e40eeb0e29c986
--- /dev/null
+++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/localCommands.js
@@ -0,0 +1,43 @@
+const {
+ buildOptions,
+ createBuild,
+ createLog,
+ createRun,
+ logOptions,
+ runOptions,
+} = require('@react-native-community/cli-platform-apple');
+
+const run = {
+ name: 'run-visionos',
+ description: 'builds your app and starts it on visionOS simulator',
+ func: createRun({platformName: 'visionos'}),
+ examples: [
+ {
+ desc: 'Run on a specific simulator',
+ cmd: 'npx @callstack/react-native-visionos run-visionos --simulator "Apple Vision Pro"',
+ },
+ ],
+ options: runOptions,
+};
+
+const log = {
+ name: 'log-visionos',
+ description: 'starts visionOS device syslog tail',
+ func: createLog({platformName: 'visionos'}),
+ options: logOptions,
+};
+
+const build = {
+ name: 'build-visionos',
+ description: 'builds your app for visionOS platform',
+ func: createBuild({platformName: 'visionos'}),
+ examples: [
+ {
+ desc: 'Build the app for all visionOS devices in Release mode',
+ cmd: 'npx @callstack/react-native-visionos build-visionos --mode "Release"',
+ },
+ ],
+ options: buildOptions,
+};
+
+module.exports = [run, log, build];
diff --git a/packages/react-native/ReactCommon/react/nativemodule/samples/ReactCommon-Samples.podspec b/packages/react-native/ReactCommon/react/nativemodule/samples/ReactCommon-Samples.podspec
index 5c6fc31aa5333d..e88b986d6e6204 100644
--- a/packages/react-native/ReactCommon/react/nativemodule/samples/ReactCommon-Samples.podspec
+++ b/packages/react-native/ReactCommon/react/nativemodule/samples/ReactCommon-Samples.podspec
@@ -49,6 +49,8 @@ Pod::Spec.new do |s|
"USE_HEADERMAP" => "YES",
"CLANG_CXX_LANGUAGE_STANDARD" => "c++20",
"GCC_WARN_PEDANTIC" => "YES" }
+ s.framework = "UIKit"
+
if ENV['USE_FRAMEWORKS']
s.header_mappings_dir = './'
end
diff --git a/packages/react-native/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTSampleTurboModule.mm b/packages/react-native/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTSampleTurboModule.mm
index c7d9666a390cc4..61cf2d54903de8 100644
--- a/packages/react-native/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTSampleTurboModule.mm
+++ b/packages/react-native/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTSampleTurboModule.mm
@@ -51,12 +51,18 @@ - (NSDictionary *)getConstants
{
__block NSDictionary *constants;
RCTUnsafeExecuteOnMainQueueSync(^{
- UIScreen *mainScreen = UIScreen.mainScreen;
- CGSize screenSize = mainScreen.bounds.size;
-
+#if TARGET_OS_VISION
+ UIApplication *app = [[UIApplication class] performSelector:@selector(sharedApplication)];
+ UIWindowScene *scene = (UIWindowScene*)[app.connectedScenes anyObject];
+ UIWindow *window = [[UIWindow alloc] initWithWindowScene:scene];
+ CGSize screenSize = window.bounds.size;
+#else
+ UIScreen *mainScreen = UIScreen.mainScreen;
+ CGSize screenSize = mainScreen.bounds.size;
+#endif
constants = @{
@"const1" : @YES,
- @"const2" : @(screenSize.width),
+ @"const2" : @(screenSize),
@"const3" : @"something",
};
});
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 94743610da2fe2..1ad4764b110c3e 100644
--- a/packages/react-native/ReactCommon/react/renderer/graphics/React-graphics.podspec
+++ b/packages/react-native/ReactCommon/react/renderer/graphics/React-graphics.podspec
@@ -53,6 +53,8 @@ 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/local-cli/localCommands.js b/packages/react-native/local-cli/localCommands.js
new file mode 100644
index 00000000000000..dc87001156ac06
--- /dev/null
+++ b/packages/react-native/local-cli/localCommands.js
@@ -0,0 +1,45 @@
+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/package.json b/packages/react-native/package.json
index e9824d707a8396..fa3318d0e45d5a 100644
--- a/packages/react-native/package.json
+++ b/packages/react-native/package.json
@@ -1,11 +1,11 @@
{
- "name": "react-native",
+ "name": "@callstack/react-native-visionos",
"version": "1000.0.0",
- "description": "A framework for building native apps using React",
+ "description": "React Native for visionOS",
"license": "MIT",
"repository": {
"type": "git",
- "url": "git+https://github.com/facebook/react-native.git",
+ "url": "https://github.com/callstack/react-native-visionos.git",
"directory": "packages/react-native"
},
"homepage": "https://reactnative.dev/",
@@ -112,6 +112,7 @@
"@react-native-community/cli": "14.0.0-alpha.2",
"@react-native-community/cli-platform-android": "14.0.0-alpha.2",
"@react-native-community/cli-platform-ios": "14.0.0-alpha.2",
+ "@react-native-community/cli-platform-apple": "14.0.0-alpha.2",
"@react-native/assets-registry": "0.75.0-main",
"@react-native/codegen": "0.75.0-main",
"@react-native/community-cli-plugin": "0.75.0-main",
diff --git a/packages/react-native/react-native.config.js b/packages/react-native/react-native.config.js
index b2dd5a5c643679..ce4cc832fbf961 100644
--- a/packages/react-native/react-native.config.js
+++ b/packages/react-native/react-native.config.js
@@ -32,8 +32,10 @@ try {
}
let ios;
+let apple;
try {
ios = require('@react-native-community/cli-platform-ios');
+ apple = require('@react-native-community/cli-platform-apple');
} catch {
if (verbose) {
console.warn(
@@ -42,6 +44,8 @@ try {
}
}
+const localCommands = require('./local-cli/localCommands');
+
const {
bundleCommand,
startCommand,
@@ -75,8 +79,14 @@ const codegenCommand = {
};
const config = {
- commands: [bundleCommand, startCommand, codegenCommand],
- platforms: {},
+ commands: [bundleCommand, startCommand, codegenCommand, ...localCommands],
+ platforms: {
+ visionos: {
+ npmPackageName: '@callstack/react-native-visionos',
+ projectConfig: apple.getProjectConfig({platformName: 'visionos'}),
+ dependencyConfig: apple.getDependencyConfig({platformName: 'visionos'}),
+ },
+ },
};
if (ios != null) {
diff --git a/packages/react-native/scripts/cocoapods/helpers.rb b/packages/react-native/scripts/cocoapods/helpers.rb
index 68017d1f0cc535..fb0260832f43af 100644
--- a/packages/react-native/scripts/cocoapods/helpers.rb
+++ b/packages/react-native/scripts/cocoapods/helpers.rb
@@ -40,6 +40,10 @@ class Constants
def self.min_ios_version_supported
return '13.4'
end
+
+ def self.min_visionos_version_supported
+ return '1.0'
+ end
def self.min_xcode_version_supported
return '14.3'
diff --git a/packages/react-native/scripts/codegen/generate-artifacts-executor.js b/packages/react-native/scripts/codegen/generate-artifacts-executor.js
index df3c1e6ac0306d..a27fe8910a35c6 100644
--- a/packages/react-native/scripts/codegen/generate-artifacts-executor.js
+++ b/packages/react-native/scripts/codegen/generate-artifacts-executor.js
@@ -59,7 +59,7 @@ const CORE_LIBRARIES_WITH_OUTPUT_FOLDER = {
),
},
};
-const REACT_NATIVE = 'react-native';
+const REACT_NATIVE = '@callstack/react-native-visionos';
const MODULES_PROTOCOLS_H_TEMPLATE_PATH = path.join(
REACT_NATIVE_PACKAGE_ROOT_FOLDER,
diff --git a/packages/react-native/scripts/react-native-xcode.sh b/packages/react-native/scripts/react-native-xcode.sh
index 08862821daa2e2..a743f58034a901 100755
--- a/packages/react-native/scripts/react-native-xcode.sh
+++ b/packages/react-native/scripts/react-native-xcode.sh
@@ -153,6 +153,7 @@ fi
--entry-file "$ENTRY_FILE" \
--platform "$BUNDLE_PLATFORM" \
--dev $DEV \
+ --resolver-option "platformExtension=visionos" \
--reset-cache \
--bundle-output "$BUNDLE_FILE" \
--assets-dest "$DEST" \
diff --git a/packages/react-native/scripts/react_native_pods.rb b/packages/react-native/scripts/react_native_pods.rb
index 7c158908c99fd2..8e10c3bde25874 100644
--- a/packages/react-native/scripts/react_native_pods.rb
+++ b/packages/react-native/scripts/react_native_pods.rb
@@ -30,11 +30,15 @@ def min_ios_version_supported
return Helpers::Constants.min_ios_version_supported
end
+def min_visionos_version_supported
+ return Helpers::Constants.min_visionos_version_supported
+end
+
# This function returns the min supported OS versions supported by React Native
# By using this function, you won't have to manually change your Podfile
# when we change the minimum version supported by the framework.
def min_supported_versions
- return { :ios => min_ios_version_supported }
+ return { :ios => min_ios_version_supported, :visionos => min_visionos_version_supported }
end
# This function prepares the project for React Native, before processing
@@ -129,6 +133,7 @@ def use_react_native! (
pod 'React-jserrorhandler', :path => "#{prefix}/ReactCommon/jserrorhandler"
pod 'React-nativeconfig', :path => "#{prefix}/ReactCommon"
pod 'RCTDeprecation', :path => "#{prefix}/ReactApple/Libraries/RCTFoundation/RCTDeprecation"
+ pod 'React-RCTSwiftExtensions', :path => "#{prefix}/Libraries/SwiftExtensions"
if hermes_enabled
setup_hermes!(:react_native_path => prefix)
@@ -156,6 +161,9 @@ def use_react_native! (
pod 'boost', :podspec => "#{prefix}/third-party-podspecs/boost.podspec"
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 46e4ff77a35e44..cdfc4b50de949d 100644
--- a/packages/react-native/sdks/hermes-engine/hermes-engine.podspec
+++ b/packages/react-native/sdks/hermes-engine/hermes-engine.podspec
@@ -12,7 +12,8 @@ react_native_path = File.join(__dir__, "..", "..")
package = JSON.parse(File.read(File.join(react_native_path, "package.json")))
version = package['version']
-source_type = hermes_source_type(version, react_native_path)
+# Temporaily build from source until visionOS supports prebuilt binaries
+source_type = HermesEngineSourceType::BUILD_FROM_GITHUB_MAIN # hermes_source_type(version, react_native_path)
source = podspec_source(source_type, version, react_native_path)
Pod::Spec.new do |spec|
@@ -35,6 +36,7 @@ Pod::Spec.new do |spec|
}
spec.ios.vendored_frameworks = "destroot/Library/Frameworks/ios/hermes.framework"
+ spec.visionos.vendored_frameworks = "destroot/Library/Frameworks/xros/hermes.framework"
spec.osx.vendored_frameworks = "destroot/Library/Frameworks/macosx/hermes.framework"
if HermesEngineSourceType::isPrebuilt(source_type) then
@@ -137,7 +139,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
. "${REACT_NATIVE_PATH}/scripts/xcode/with-environment.sh"
diff --git a/packages/react-native/sdks/hermes-engine/utils/build-hermesc-xcode.sh b/packages/react-native/sdks/hermes-engine/utils/build-hermesc-xcode.sh
index 132ee54c734566..f536b0c4c3b01c 100755
--- a/packages/react-native/sdks/hermes-engine/utils/build-hermesc-xcode.sh
+++ b/packages/react-native/sdks/hermes-engine/utils/build-hermesc-xcode.sh
@@ -9,6 +9,21 @@ set -x -e
hermesc_dir_path="$1"; shift
jsi_path="$1"
+
+# VisionOS support has been added to CMake from version 3.28.0 onwards. Error out if the version is lower.
+function check_cmake_version {
+ required_version="3.28.0"
+ cmake_version=$($CMAKE_BINARY --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n 1)
+
+ if ! printf "%s\n%s\n" "$required_version" "$cmake_version" | sort -V | head -n 1 | grep -q "$required_version"; then
+ echo "error: CMake version $required_version or higher is required. Found: $cmake_version"
+ exit 1
+ fi
+}
+
+check_cmake_version
+
+
# This script is supposed to be executed from Xcode "run script" phase.
# Xcode sets up its build environment based on the build target (iphone, iphonesimulator, macodsx).
# We want to make sure that hermesc is built for mac.
diff --git a/packages/react-native/template/App.tsx b/packages/react-native/template/App.tsx
new file mode 100644
index 00000000000000..e50b7452929dd2
--- /dev/null
+++ b/packages/react-native/template/App.tsx
@@ -0,0 +1,93 @@
+/**
+ * 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
new file mode 100644
index 00000000000000..d8a58b2b792d3d
--- /dev/null
+++ b/packages/react-native/template/metro.config.js
@@ -0,0 +1,20 @@
+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
new file mode 100644
index 00000000000000..629f6ae71cdb46
--- /dev/null
+++ b/packages/react-native/template/package.json
@@ -0,0 +1,39 @@
+{
+ "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
new file mode 100644
index 00000000000000..55edc7d7881737
--- /dev/null
+++ b/packages/react-native/template/visionos/HelloWorld.xcodeproj/project.pbxproj
@@ -0,0 +1,691 @@
+// !$*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 */; };
+ 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 */,
+ );
+ 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
new file mode 100644
index 00000000000000..b57be22ab2d66f
--- /dev/null
+++ b/packages/react-native/template/visionos/HelloWorld.xcodeproj/xcshareddata/xcschemes/HelloWorld.xcscheme
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/react-native/template/visionos/HelloWorld/App.swift b/packages/react-native/template/visionos/HelloWorld/App.swift
new file mode 100644
index 00000000000000..c1d601b2201ba9
--- /dev/null
+++ b/packages/react-native/template/visionos/HelloWorld/App.swift
@@ -0,0 +1,12 @@
+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
new file mode 100644
index 00000000000000..1583449a06a0ae
--- /dev/null
+++ b/packages/react-native/template/visionos/HelloWorld/AppDelegate.swift
@@ -0,0 +1,17 @@
+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
new file mode 100644
index 00000000000000..81213230deb40d
--- /dev/null
+++ b/packages/react-native/template/visionos/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,53 @@
+{
+ "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
new file mode 100644
index 00000000000000..2d92bd53fdb222
--- /dev/null
+++ b/packages/react-native/template/visionos/HelloWorld/Images.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "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
new file mode 100644
index 00000000000000..2f57133ef1d075
--- /dev/null
+++ b/packages/react-native/template/visionos/HelloWorld/Info.plist
@@ -0,0 +1,57 @@
+
+
+
+
+ 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/HelloWorldTests/HelloWorldTests.m b/packages/react-native/template/visionos/HelloWorldTests/HelloWorldTests.m
new file mode 100644
index 00000000000000..884d405d6579c6
--- /dev/null
+++ b/packages/react-native/template/visionos/HelloWorldTests/HelloWorldTests.m
@@ -0,0 +1,66 @@
+#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
new file mode 100644
index 00000000000000..ba72822e8728ef
--- /dev/null
+++ b/packages/react-native/template/visionos/HelloWorldTests/Info.plist
@@ -0,0 +1,24 @@
+
+
+
+
+ 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
new file mode 100644
index 00000000000000..c6d5ba6c29b336
--- /dev/null
+++ b/packages/react-native/template/visionos/Podfile
@@ -0,0 +1,40 @@
+# 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
new file mode 100644
index 00000000000000..3d5782c71568d3
--- /dev/null
+++ b/packages/react-native/template/visionos/_xcode.env
@@ -0,0 +1,11 @@
+# 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
new file mode 100644
index 00000000000000..7e65ab07b1710a
--- /dev/null
+++ b/packages/react-native/third-party-podspecs/SocketRocket.podspec
@@ -0,0 +1,21 @@
+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/tsconfig.json b/packages/react-native/types/tsconfig.json
index 7cabbef31792d9..8f693581db76f3 100644
--- a/packages/react-native/types/tsconfig.json
+++ b/packages/react-native/types/tsconfig.json
@@ -1,15 +1,18 @@
{
- "compilerOptions": {
- "module": "commonjs",
- "lib": ["es6"],
- "noImplicitAny": true,
- "noImplicitThis": true,
- "strictFunctionTypes": true,
- "strictNullChecks": true,
- "types": [],
- "jsx": "react",
- "noEmit": true,
- "forceConsistentCasingInFileNames": true,
- "paths": {"react-native": ["."]}
+ "compilerOptions": {
+ "module": "commonjs",
+ "lib": ["es6"],
+ "noImplicitAny": true,
+ "noImplicitThis": true,
+ "strictFunctionTypes": true,
+ "strictNullChecks": true,
+ "types": [],
+ "jsx": "react",
+ "noEmit": true,
+ "forceConsistentCasingInFileNames": true,
+ "paths": {
+ "react-native": ["."],
+ "react-native/*": ["../*"]
}
}
+}
diff --git a/packages/rn-tester/NativeModuleExample/ScreenshotManager.podspec b/packages/rn-tester/NativeModuleExample/ScreenshotManager.podspec
index 17daaf5934d9fd..3177cf590fe73a 100644
--- a/packages/rn-tester/NativeModuleExample/ScreenshotManager.podspec
+++ b/packages/rn-tester/NativeModuleExample/ScreenshotManager.podspec
@@ -21,6 +21,7 @@ Pod::Spec.new do |s|
s.source_files = "**/*.{h,m,mm,swift}"
s.requires_arc = true
+ s.framework = ["UIKit", "CoreGraphics"]
install_modules_dependencies(s)
end
diff --git a/packages/rn-tester/Podfile b/packages/rn-tester/Podfile
index 7e723ec52341e6..819991e9294562 100644
--- a/packages/rn-tester/Podfile
+++ b/packages/rn-tester/Podfile
@@ -67,10 +67,15 @@ target 'RNTester' do
pods('RNTester')
end
+target('RNTester-visionOS') do
+ platform :visionos, min_visionos_version_supported
+ pods('RNTester-visionOS')
+end
+
target 'RNTesterUnitTests' do
pods('RNTesterUnitTests')
pod 'React-RCTTest', :path => "./RCTTest"
- pod 'OCMock', '~> 3.9.1'
+ pod 'OCMock', :git => 'https://github.com/erikdoe/ocmock.git', :tag => 'v3.9.2'
end
target 'RNTesterIntegrationTests' do
diff --git a/packages/rn-tester/Podfile.lock b/packages/rn-tester/Podfile.lock
index 07b5b5b40b7d4e..9ab010d908ccd9 100644
--- a/packages/rn-tester/Podfile.lock
+++ b/packages/rn-tester/Podfile.lock
@@ -57,7 +57,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- - OCMock (3.9.1)
+ - OCMock (3.9.2)
- RCT-Folly (2024.01.01.00):
- boost
- DoubleConversion
@@ -93,6 +93,8 @@ PODS:
- React-RCTSettings (= 1000.0.0)
- React-RCTText (= 1000.0.0)
- React-RCTVibration (= 1000.0.0)
+ - React-RCTWindowManager (= 1000.0.0)
+ - React-RCTXR (= 1000.0.0)
- React-callinvoker (1000.0.0)
- React-Core (1000.0.0):
- glog
@@ -109,7 +111,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/CoreModulesHeaders (1000.0.0):
- glog
@@ -126,7 +128,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/Default (1000.0.0):
- glog
@@ -142,7 +144,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/DevSupport (1000.0.0):
- glog
@@ -160,7 +162,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/RCTActionSheetHeaders (1000.0.0):
- glog
@@ -177,7 +179,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/RCTAnimationHeaders (1000.0.0):
- glog
@@ -194,7 +196,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/RCTBlobHeaders (1000.0.0):
- glog
@@ -211,7 +213,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/RCTImageHeaders (1000.0.0):
- glog
@@ -228,7 +230,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/RCTLinkingHeaders (1000.0.0):
- glog
@@ -245,7 +247,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/RCTNetworkHeaders (1000.0.0):
- glog
@@ -262,7 +264,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/RCTPushNotificationHeaders (1000.0.0):
- glog
@@ -279,7 +281,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/RCTSettingsHeaders (1000.0.0):
- glog
@@ -296,7 +298,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/RCTTextHeaders (1000.0.0):
- glog
@@ -313,7 +315,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/RCTVibrationHeaders (1000.0.0):
- glog
@@ -330,7 +332,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/RCTWebSocket (1000.0.0):
- glog
@@ -347,7 +349,41 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.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.0.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
+ - React-jsinspector
+ - React-perflogger
+ - React-runtimescheduler
+ - React-utils
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-CoreModules (1000.0.0):
- DoubleConversion
@@ -362,7 +398,7 @@ PODS:
- React-RCTImage (= 1000.0.0)
- ReactCodegen
- ReactCommon
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- React-cxxreact (1000.0.0):
- boost
- DoubleConversion
@@ -1268,6 +1304,10 @@ PODS:
- React-NativeModulesApple
- ReactCodegen
- ReactCommon
+ - React-RCTSwiftExtensions (1000.0.0):
+ - React-Core
+ - React-RCTWindowManager
+ - React-RCTXR
- React-RCTTest (1000.0.0):
- RCT-Folly (= 2024.01.01.00)
- React-Core (= 1000.0.0)
@@ -1446,7 +1486,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- - SocketRocket (0.7.0)
+ - SocketRocket (0.7.0.1)
- Yoga (0.0.0)
DEPENDENCIES:
@@ -1458,7 +1498,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`)
- RCT-Folly (from `../react-native/third-party-podspecs/RCT-Folly.podspec`)
- RCT-Folly/Fabric (from `../react-native/third-party-podspecs/RCT-Folly.podspec`)
- RCTDeprecation (from `../react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation`)
@@ -1500,6 +1540,7 @@ DEPENDENCIES:
- React-RCTNetwork (from `../react-native/Libraries/Network`)
- React-RCTPushNotification (from `../react-native/Libraries/PushNotificationIOS`)
- React-RCTSettings (from `../react-native/Libraries/Settings`)
+ - React-RCTSwiftExtensions (from `../react-native/Libraries/SwiftExtensions`)
- React-RCTTest (from `./RCTTest`)
- React-RCTText (from `../react-native/Libraries/Text`)
- React-RCTVibration (from `../react-native/Libraries/Vibration`)
@@ -1516,13 +1557,9 @@ DEPENDENCIES:
- 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:
- - OCMock
- - SocketRocket
-
EXTERNAL SOURCES:
boost:
:podspec: "../react-native/third-party-podspecs/boost.podspec"
@@ -1541,6 +1578,9 @@ EXTERNAL SOURCES:
:path: NativeComponentExample
NativeCxxModuleExample:
:path: NativeCxxModuleExample
+ OCMock:
+ :git: https://github.com/erikdoe/ocmock.git
+ :tag: v3.9.2
RCT-Folly:
:podspec: "../react-native/third-party-podspecs/RCT-Folly.podspec"
RCTDeprecation:
@@ -1619,6 +1659,8 @@ EXTERNAL SOURCES:
:path: "../react-native/Libraries/PushNotificationIOS"
React-RCTSettings:
:path: "../react-native/Libraries/Settings"
+ React-RCTSwiftExtensions:
+ :path: "../react-native/Libraries/SwiftExtensions"
React-RCTTest:
:path: "./RCTTest"
React-RCTText:
@@ -1651,6 +1693,8 @@ EXTERNAL SOURCES:
: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"
@@ -1722,6 +1766,75 @@ SPEC CHECKSUMS:
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
Yoga: f58ba5e0ac1e7eb3ef4caedcf80c5aa39985b039
-PODFILE CHECKSUM: 60b84dd598fc04e9ed84dbc82e2cb3b99b1d7adf
+SPEC CHECKSUMS:
+ boost: 8f1e9b214fa11f71081fc8ecd5fad3daf221cf7f
+ DoubleConversion: 26c660c8d88372cca1a67f8101d2d962a7064361
+ FBLazyVector: a8b6874b6148add7ee784f18e5899416a2004431
+ fmt: 5d9ffa7ccba126c08b730252123601d514652320
+ glog: 4f05d17aa39a829fee878689fc9a41af587fabba
+ hermes-engine: bca1a39d82a348d5da84cd78a69763e639ca3c03
+ MyNativeView: 285c6f70650ff53a276f7086047921e617a4d0e3
+ NativeCxxModuleExample: 1cd42853b5ec241c6b5e70f2dd4bbc26feb97b39
+ OCMock: 267d92c078398b7ce11d99e811e3a402744c06bc
+ RCT-Folly: 38265df22721cd15cc13ba692c23a52cceaf3752
+ RCTDeprecation: 3808e36294137f9ee5668f4df2e73dc079cd1dcf
+ RCTRequired: 8868653a51ddc1b8fa89095bdfc2c630644b3cc4
+ RCTTypeSafety: 84fa2670982ff1553c410e1941aa660c63819c07
+ React: be3288bb746209d28f834f0966e7bfa14ef4c635
+ React-callinvoker: f12cfb7e8a45074285da006f17cf855119af1a40
+ React-Core: 5035595b0044438ac2101999f66d502a0a310287
+ React-CoreModules: a996498eb88ddd84dd0d331781b3ce3b7810f840
+ React-cxxreact: be48d9b7526ccfd4bc4d214353614e25788142c8
+ React-debug: 5930ea86e847a28159f5f8bf6739d8e838d455bf
+ React-Fabric: f24838ecc4df240c4b2a2c32167905a051aa301d
+ React-FabricImage: aba0fc43528c1c6352470259ce28ffcb695aa372
+ React-featureflags: c72038c7f57542702cbb4ab5047cecf4d44ff5d8
+ React-featureflagsnativemodule: cd3090f4d8ba3c1e414721099412c85499338a3a
+ React-graphics: d943be9e0000e748753597c706f7c6ccb424a023
+ React-hermes: 857325bf47b34af4c3a678bbe418af29118ab704
+ React-ImageManager: 269e963e2651b96c0c8d099dfa7bce6e338e2a21
+ React-jserrorhandler: 5b2c65f502d4266f565b272c02d7a1cb5e6b1704
+ React-jsi: f1289e84582f0164584a1ffbaf69c42f316aa7c1
+ React-jsiexecutor: b1da8bf3a12196de96c31585d9aad2f3ce18667e
+ React-jsinspector: adbdb51662599ff97c60495207670a44d755978b
+ React-jsitracing: a680754082542a2d8794ef1446d8305917695ed6
+ React-logger: 1d95653487cc3981bc3597397031dcc17b69f7bf
+ React-Mapbuffer: 65326a76ad5353d2f1109e3c2a54278e3ff21b5d
+ React-microtasksnativemodule: 1b271a825fbda231f40a1c2017699ab4caefe1dd
+ React-nativeconfig: f6b75522748064ae86c07039c93aefb652d3f4a0
+ React-NativeModulesApple: 4902fd29dddbdba95e0c51213ecaa20fb26d9c93
+ React-perflogger: 48cf3cd197624766ec62b6263751768ccdb968dd
+ React-RCTActionSheet: f9b19504e2f84da35e2ab402421946cc3d477ef9
+ React-RCTAnimation: be5080867ee095d546b24ff66ae217b211970463
+ React-RCTAppDelegate: 17fa290d2ce3e9c8d81f100d7d5e9eab4427be21
+ React-RCTBlob: 0f25d3a6b824875ef8cd169fc63080ce5085fdcb
+ React-RCTFabric: aeab70fdc29832176a5849f67f8dac620e33a89a
+ React-RCTImage: 060883e7bb937b62e9a8fb8583b4ca84f4a5f743
+ React-RCTLinking: cd478cbd83bfd2bc40686dbe0fef971efd7f59f2
+ React-RCTNetwork: 19e4e24ed15880bf84cb5570dd2ef29b35c24180
+ React-RCTPushNotification: 88c29adf2747ba7495bccec662564748e6ca626d
+ React-RCTSettings: 4f966b6455c9f73aac0185056c7969e37aa0410b
+ React-RCTSwiftExtensions: ddfa9ba161df98300d31b1c7ee1a83b50110ce84
+ React-RCTTest: b1250356c778991ee70d4b2dd950a1559883fef9
+ React-RCTText: 3873ebf3f5c6d3011c2bb71d3b1f6c44cf1c4b57
+ React-RCTVibration: d70ec633dbf05668999931827d27e74943d94618
+ React-RCTWindowManager: b10830e71b5b0579e983c98970539df9a9c81eea
+ React-RCTXR: b6c219508272317d4449c9ca73b691e60aaee723
+ React-rendererdebug: 5ad8169f3dc55c751f68e010a97c0095b30fdc0e
+ React-rncore: fde1aa114ae442a50cf2c105b211f1fe4df8d171
+ React-RuntimeApple: 1caacd31ffd03f2325c86b69faf7faaa21c74983
+ React-RuntimeCore: 0d8722c0375f1e1994a1a928f083f1b8d4fbfaaa
+ React-runtimeexecutor: 5042037ada501a8f43c16c99ec0dfff7c0a2fdec
+ React-RuntimeHermes: 971d25b13e7018e7d6084df06527f06a0d4d2158
+ React-runtimescheduler: 986d92bd957e012341ae4416ffec3b36528c162c
+ React-utils: 0a51e4008a443b6d2beb484a5777558881fd9e08
+ ReactCodegen: 2fa2bfb8df604e5bbf2462cf3cced313c3131b96
+ ReactCommon: f334f2b7af5bb60b36a577489f71349cbfc6bc5f
+ ReactCommon-Samples: 028f1b033386b9f33af521748fa58b1188766818
+ ScreenshotManager: 662151998cf5859591e72c76ceb9ebc6d04b425b
+ SocketRocket: 0ba3e799f983d2dfa878777017659ef6c866e5c6
+ Yoga: 94229f0b73e033393211963906f86db91056fe2b
+
+PODFILE CHECKSUM: 7e999b8158f1055609ef4491bc35f1ad658fdd6c
COCOAPODS: 1.14.3
diff --git a/packages/rn-tester/RNTester-visionOS/App.swift b/packages/rn-tester/RNTester-visionOS/App.swift
new file mode 100644
index 00000000000000..39224b803cce1b
--- /dev/null
+++ b/packages/rn-tester/RNTester-visionOS/App.swift
@@ -0,0 +1,12 @@
+import SwiftUI
+import React
+import React_RCTSwiftExtensions
+
+@main
+struct RNTesterApp: App {
+ @UIApplicationDelegateAdaptor var delegate: AppDelegate
+
+ var body: some Scene {
+ RCTMainWindow(moduleName: "RNTesterApp")
+ }
+}
diff --git a/packages/rn-tester/RNTester-visionOS/AppDelegate.swift b/packages/rn-tester/RNTester-visionOS/AppDelegate.swift
new file mode 100644
index 00000000000000..cf164ab3877837
--- /dev/null
+++ b/packages/rn-tester/RNTester-visionOS/AppDelegate.swift
@@ -0,0 +1,13 @@
+import UIKit
+import React
+import React_RCTAppDelegate
+
+class AppDelegate: RCTAppDelegate {
+ override func sourceURL(for bridge: RCTBridge) -> URL? {
+ self.bundleURL()
+ }
+
+ override func bundleURL() -> URL? {
+ RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "js/RNTesterApp.ios")
+ }
+}
diff --git a/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json b/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 00000000000000..90f92021701acf
--- /dev/null
+++ b/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,13 @@
+{
+ "images" : [
+ {
+ "filename" : "back.jpg",
+ "idiom" : "vision",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/back.jpg b/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/back.jpg
new file mode 100644
index 00000000000000..3abf32df01e9af
Binary files /dev/null and b/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/back.jpg differ
diff --git a/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json b/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json
new file mode 100644
index 00000000000000..73c00596a7fca3
--- /dev/null
+++ b/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Contents.json b/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Contents.json
new file mode 100644
index 00000000000000..950af4d85a8e15
--- /dev/null
+++ b/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Contents.json
@@ -0,0 +1,17 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "layers" : [
+ {
+ "filename" : "Front.solidimagestacklayer"
+ },
+ {
+ "filename" : "Middle.solidimagestacklayer"
+ },
+ {
+ "filename" : "Back.solidimagestacklayer"
+ }
+ ]
+}
diff --git a/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json b/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 00000000000000..75fdd994465b3f
--- /dev/null
+++ b/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,13 @@
+{
+ "images" : [
+ {
+ "filename" : "front.png",
+ "idiom" : "vision",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/front.png b/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/front.png
new file mode 100644
index 00000000000000..bddbc150c298d2
Binary files /dev/null and b/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/front.png differ
diff --git a/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json b/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json
new file mode 100644
index 00000000000000..73c00596a7fca3
--- /dev/null
+++ b/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json b/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 00000000000000..04056a547f776e
--- /dev/null
+++ b/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "idiom" : "vision",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json b/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json
new file mode 100644
index 00000000000000..73c00596a7fca3
--- /dev/null
+++ b/packages/rn-tester/RNTester-visionOS/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/packages/rn-tester/RNTester-visionOS/Assets.xcassets/Contents.json b/packages/rn-tester/RNTester-visionOS/Assets.xcassets/Contents.json
new file mode 100644
index 00000000000000..da4a164c918651
--- /dev/null
+++ b/packages/rn-tester/RNTester-visionOS/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/packages/rn-tester/RNTester-visionOS/Info.plist b/packages/rn-tester/RNTester-visionOS/Info.plist
new file mode 100644
index 00000000000000..940d4ef45518db
--- /dev/null
+++ b/packages/rn-tester/RNTester-visionOS/Info.plist
@@ -0,0 +1,15 @@
+
+
+
+
+ UIApplicationSceneManifest
+
+ UIApplicationPreferredDefaultSceneSessionRole
+ UIWindowSceneSessionRoleApplication
+ UIApplicationSupportsMultipleScenes
+
+ UISceneConfigurations
+
+
+
+
diff --git a/packages/rn-tester/RNTester-visionOS/Preview Content/Preview Assets.xcassets/Contents.json b/packages/rn-tester/RNTester-visionOS/Preview Content/Preview Assets.xcassets/Contents.json
new file mode 100644
index 00000000000000..73c00596a7fca3
--- /dev/null
+++ b/packages/rn-tester/RNTester-visionOS/Preview Content/Preview Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/packages/rn-tester/RNTester/AppDelegate.mm b/packages/rn-tester/RNTester/AppDelegate.mm
index 5ca3ce39faa6e5..98be3fb1ada575 100644
--- a/packages/rn-tester/RNTester/AppDelegate.mm
+++ b/packages/rn-tester/RNTester/AppDelegate.mm
@@ -107,6 +107,7 @@ - (void)application:(__unused UIApplication *)application
[RCTPushNotificationManager didFailToRegisterForRemoteNotificationsWithError:error];
}
+#if !TARGET_OS_VISION
#pragma mark - UNUserNotificationCenterDelegate
// Required for the remoteNotificationReceived and localNotificationReceived events
@@ -136,6 +137,7 @@ - (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 ce240545a6a775..92013f258662bf 100644
--- a/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj
+++ b/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj
@@ -7,17 +7,21 @@
objects = {
/* Begin PBXBuildFile section */
- 08E25EBE4A584CD7B70FBB1E /* libPods-RNTester.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D74056A5352F0925816E50E0 /* libPods-RNTester.a */; };
+ 111FD3845C7358250C2702B6 /* libPods-RNTesterIntegrationTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63C6B5E1C2465D85E9BDB6E5 /* libPods-RNTesterIntegrationTests.a */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
2DDEF0101F84BF7B00DBDF73 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2DDEF00F1F84BF7B00DBDF73 /* Images.xcassets */; };
383889DA23A7398900D06C3E /* RCTConvert_UIColorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 383889D923A7398900D06C3E /* RCTConvert_UIColorTests.m */; };
3D2AFAF51D646CF80089D1A3 /* legacy_image@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3D2AFAF41D646CF80089D1A3 /* legacy_image@2x.png */; };
5C60EB1C226440DB0018C04F /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C60EB1B226440DB0018C04F /* AppDelegate.mm */; };
+ 763DC37D2B0F824400D2C0C5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 763DC37C2B0F824400D2C0C5 /* Assets.xcassets */; };
+ 763DC3802B0F824400D2C0C5 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 763DC37F2B0F824400D2C0C5 /* Preview Assets.xcassets */; };
+ 76E4BB282B34909800B02A15 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76E4BB272B34909800B02A15 /* App.swift */; };
+ 76E4BB2C2B34932200B02A15 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76E4BB2B2B34932200B02A15 /* AppDelegate.swift */; };
8145AE06241172D900A3F8DA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8145AE05241172D900A3F8DA /* LaunchScreen.storyboard */; };
832F45BB2A8A6E1F0097B4E6 /* SwiftTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 832F45BA2A8A6E1F0097B4E6 /* SwiftTest.swift */; };
- BEB82277FE76227A15DED9EF /* libPods-RNTesterIntegrationTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 77E101C7D8E22A8E70EE76DF /* libPods-RNTesterIntegrationTests.a */; };
+ A425EC3215FAAE553BB048E9 /* libPods-RNTester-visionOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6DF8AE154B671749B5880FDB /* libPods-RNTester-visionOS.a */; };
CD10C7A5290BD4EB0033E1ED /* RCTEventEmitterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CD10C7A4290BD4EB0033E1ED /* RCTEventEmitterTests.m */; };
- D626973C1F0D4ABDE2F9028A /* libPods-RNTesterUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D8DE57E3292D41E28251988A /* libPods-RNTesterUnitTests.a */; };
+ DD6FAB12C0152128DD2DA1BE /* libPods-RNTester.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 175067970892CD30B8B0A8E0 /* libPods-RNTester.a */; };
E62F11832A5C6580000BF1C8 /* FlexibleSizeExampleView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 27F441E81BEBE5030039B79C /* FlexibleSizeExampleView.mm */; };
E62F11842A5C6584000BF1C8 /* UpdatePropertiesExampleView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 272E6B3C1BEA849E001FCF37 /* UpdatePropertiesExampleView.mm */; };
E7C1241A22BEC44B00DA25C0 /* RNTesterIntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E7C1241922BEC44B00DA25C0 /* RNTesterIntegrationTests.m */; };
@@ -56,7 +60,6 @@
E7DB216422B2F3EC005AC45F /* RCTUIManagerScenarioTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E7DB215F22B2F3EC005AC45F /* RCTUIManagerScenarioTests.m */; };
E7DB216722B2F69F005AC45F /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7DB213022B2C649005AC45F /* JavaScriptCore.framework */; };
E7DB218C22B41FCD005AC45F /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7DB218B22B41FCD005AC45F /* XCTest.framework */; };
- F0D621C32BBB9E38005960AC /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = F0D621C22BBB9E38005960AC /* PrivacyInfo.xcprivacy */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -81,6 +84,8 @@
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = RNTester/AppDelegate.h; sourceTree = ""; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = RNTester/Info.plist; sourceTree = ""; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = RNTester/main.m; sourceTree = ""; };
+ 175067970892CD30B8B0A8E0 /* libPods-RNTester.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTester.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 22B01F4E0F077250C6C20B54 /* Pods-RNTester-visionOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester-visionOS.debug.xcconfig"; path = "Target Support Files/Pods-RNTester-visionOS/Pods-RNTester-visionOS.debug.xcconfig"; sourceTree = ""; };
272E6B3B1BEA849E001FCF37 /* UpdatePropertiesExampleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UpdatePropertiesExampleView.h; path = RNTester/NativeExampleViews/UpdatePropertiesExampleView.h; sourceTree = ""; };
272E6B3C1BEA849E001FCF37 /* UpdatePropertiesExampleView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = UpdatePropertiesExampleView.mm; path = RNTester/NativeExampleViews/UpdatePropertiesExampleView.mm; sourceTree = ""; };
2734C5E31C1D7A09BF872585 /* Pods-RNTester.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester.debug.xcconfig"; path = "Target Support Files/Pods-RNTester/Pods-RNTester.debug.xcconfig"; sourceTree = ""; };
@@ -90,9 +95,17 @@
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 = ""; };
+ 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; };
66C3087F2D5BF762FE9E6422 /* Pods-RNTesterIntegrationTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterIntegrationTests.debug.xcconfig"; path = "Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests.debug.xcconfig"; sourceTree = ""; };
- 77E101C7D8E22A8E70EE76DF /* libPods-RNTesterIntegrationTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterIntegrationTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 6DF8AE154B671749B5880FDB /* libPods-RNTester-visionOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTester-visionOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 763DC3722B0F824200D2C0C5 /* RNTester-visionOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "RNTester-visionOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 763DC37C2B0F824400D2C0C5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ 763DC37F2B0F824400D2C0C5 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
+ 763DC3812B0F824400D2C0C5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ 76E4BB272B34909800B02A15 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = ""; };
+ 76E4BB2B2B34932200B02A15 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
7CDA7A212644C6BB8C0D00D8 /* Pods-RNTesterIntegrationTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterIntegrationTests.release.xcconfig"; path = "Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests.release.xcconfig"; sourceTree = ""; };
8145AE05241172D900A3F8DA /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = RNTester/LaunchScreen.storyboard; sourceTree = ""; };
832F45BA2A8A6E1F0097B4E6 /* SwiftTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SwiftTest.swift; path = RNTester/SwiftTest.swift; sourceTree = ""; };
@@ -100,8 +113,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 = ""; };
AC474BFB29BBD4A1002BDAED /* RNTester.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; name = RNTester.xctestplan; path = RNTester/RNTester.xctestplan; sourceTree = ""; };
CD10C7A4290BD4EB0033E1ED /* RCTEventEmitterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTEventEmitterTests.m; sourceTree = ""; };
- D74056A5352F0925816E50E0 /* libPods-RNTester.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTester.a"; sourceTree = BUILT_PRODUCTS_DIR; };
- D8DE57E3292D41E28251988A /* libPods-RNTesterUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 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 = ""; };
E7C1241922BEC44B00DA25C0 /* RNTesterIntegrationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNTesterIntegrationTests.m; sourceTree = ""; };
E7DB209F22B2BA84005AC45F /* RNTesterUnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RNTesterUnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -171,7 +183,15 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 08E25EBE4A584CD7B70FBB1E /* libPods-RNTester.a in Frameworks */,
+ DD6FAB12C0152128DD2DA1BE /* libPods-RNTester.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 763DC36F2B0F824200D2C0C5 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A425EC3215FAAE553BB048E9 /* libPods-RNTester-visionOS.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -180,7 +200,7 @@
buildActionMask = 2147483647;
files = (
E7DB213122B2C649005AC45F /* JavaScriptCore.framework in Frameworks */,
- D626973C1F0D4ABDE2F9028A /* libPods-RNTesterUnitTests.a in Frameworks */,
+ F37EF1CF1FC0B3DD56375DC7 /* libPods-RNTesterUnitTests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -190,7 +210,7 @@
files = (
E7DB218C22B41FCD005AC45F /* XCTest.framework in Frameworks */,
E7DB216722B2F69F005AC45F /* JavaScriptCore.framework in Frameworks */,
- BEB82277FE76227A15DED9EF /* libPods-RNTesterIntegrationTests.a in Frameworks */,
+ 111FD3845C7358250C2702B6 /* libPods-RNTesterIntegrationTests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -261,9 +281,10 @@
E7DB211822B2BD53005AC45F /* libReact-RCTText.a */,
E7DB211A22B2BD53005AC45F /* libReact-RCTVibration.a */,
E7DB212222B2BD53005AC45F /* libyoga.a */,
- D74056A5352F0925816E50E0 /* libPods-RNTester.a */,
- 77E101C7D8E22A8E70EE76DF /* libPods-RNTesterIntegrationTests.a */,
- D8DE57E3292D41E28251988A /* libPods-RNTesterUnitTests.a */,
+ 175067970892CD30B8B0A8E0 /* libPods-RNTester.a */,
+ 63C6B5E1C2465D85E9BDB6E5 /* libPods-RNTesterIntegrationTests.a */,
+ D6942D0981036096211E5BDC /* libPods-RNTesterUnitTests.a */,
+ 6DF8AE154B671749B5880FDB /* libPods-RNTester-visionOS.a */,
);
name = Frameworks;
sourceTree = "";
@@ -275,12 +296,41 @@
name = Fabric;
sourceTree = "";
};
+ 763DC3732B0F824200D2C0C5 /* RNTester-visionOS */ = {
+ isa = PBXGroup;
+ children = (
+ 76E4BB2B2B34932200B02A15 /* AppDelegate.swift */,
+ 76E4BB272B34909800B02A15 /* App.swift */,
+ 763DC37C2B0F824400D2C0C5 /* Assets.xcassets */,
+ 763DC3812B0F824400D2C0C5 /* Info.plist */,
+ 763DC37E2B0F824400D2C0C5 /* Preview Content */,
+ );
+ path = "RNTester-visionOS";
+ sourceTree = "";
+ };
+ 763DC3742B0F824200D2C0C5 /* Packages */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ path = Packages;
+ sourceTree = "";
+ };
+ 763DC37E2B0F824400D2C0C5 /* Preview Content */ = {
+ isa = PBXGroup;
+ children = (
+ 763DC37F2B0F824400D2C0C5 /* Preview Assets.xcassets */,
+ );
+ path = "Preview Content";
+ sourceTree = "";
+ };
83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup;
children = (
13B07FAE1A68108700A75B9A /* RNTester */,
E7DB20A022B2BA84005AC45F /* RNTesterUnitTests */,
E7DB215422B2F332005AC45F /* RNTesterIntegrationTests */,
+ 763DC3732B0F824200D2C0C5 /* RNTester-visionOS */,
+ 763DC3742B0F824200D2C0C5 /* Packages */,
83CBBA001A601CBA00E9B192 /* Products */,
2DE7E7D81FB2A4F3009E225D /* Frameworks */,
E23BD6487B06BD71F1A86914 /* Pods */,
@@ -296,6 +346,7 @@
13B07F961A680F5B00A75B9A /* RNTester.app */,
E7DB209F22B2BA84005AC45F /* RNTesterUnitTests.xctest */,
E7DB215322B2F332005AC45F /* RNTesterIntegrationTests.xctest */,
+ 763DC3722B0F824200D2C0C5 /* RNTester-visionOS.app */,
);
name = Products;
sourceTree = "";
@@ -309,6 +360,8 @@
7CDA7A212644C6BB8C0D00D8 /* Pods-RNTesterIntegrationTests.release.xcconfig */,
359825B9A5AE4A3F4AA612DD /* Pods-RNTesterUnitTests.debug.xcconfig */,
8BFB9C61D7BDE894E24BF24F /* Pods-RNTesterUnitTests.release.xcconfig */,
+ 22B01F4E0F077250C6C20B54 /* Pods-RNTester-visionOS.debug.xcconfig */,
+ 54DDA3DF154A732E76DCCEE8 /* Pods-RNTester-visionOS.release.xcconfig */,
);
path = Pods;
sourceTree = "";
@@ -378,8 +431,8 @@
13B07F8E1A680F5B00A75B9A /* Resources */,
68CD48B71D2BCB2C007E06A9 /* Build JS Bundle */,
79E8BE2B119D4C5CCD2F04B3 /* [RN] Copy Hermes Framework */,
- 02B6FEF7E86B613B42F31284 /* [CP] Embed Pods Frameworks */,
5625E703156DD564DE9175B0 /* [CP] Copy Pods Resources */,
+ 010C6668749A96FAD021029C /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@@ -390,6 +443,27 @@
productReference = 13B07F961A680F5B00A75B9A /* RNTester.app */;
productType = "com.apple.product-type.application";
};
+ 763DC3712B0F824200D2C0C5 /* RNTester-visionOS */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 763DC3842B0F824400D2C0C5 /* Build configuration list for PBXNativeTarget "RNTester-visionOS" */;
+ buildPhases = (
+ 28541C798E9769A525E7C14E /* [CP] Check Pods Manifest.lock */,
+ 763DC36E2B0F824200D2C0C5 /* Sources */,
+ 763DC36F2B0F824200D2C0C5 /* Frameworks */,
+ 763DC3702B0F824200D2C0C5 /* Resources */,
+ 763DC38C2B10A42B00D2C0C5 /* Build JS Bundle */,
+ D88C968E3153313E61AE696C /* [CP] Embed Pods Frameworks */,
+ 8634A0D0E14BF96B8A2F986B /* [CP] Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "RNTester-visionOS";
+ productName = "RNTester-visionOS";
+ productReference = 763DC3722B0F824200D2C0C5 /* RNTester-visionOS.app */;
+ productType = "com.apple.product-type.application";
+ };
E7DB209E22B2BA84005AC45F /* RNTesterUnitTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = E7DB20A622B2BA84005AC45F /* Build configuration list for PBXNativeTarget "RNTesterUnitTests" */;
@@ -398,8 +472,8 @@
E7DB209B22B2BA84005AC45F /* Sources */,
E7DB209C22B2BA84005AC45F /* Frameworks */,
E7DB209D22B2BA84005AC45F /* Resources */,
- A904658C20543C2EDC217D15 /* [CP] Embed Pods Frameworks */,
01934C30687B8C926E4F59CD /* [CP] Copy Pods Resources */,
+ 4E3C3D35C3AFA4B5CE6A544E /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@@ -419,8 +493,8 @@
E7DB214F22B2F332005AC45F /* Sources */,
E7DB215022B2F332005AC45F /* Frameworks */,
E7DB215122B2F332005AC45F /* Resources */,
- 4F27ACC9DB890B37D6C267F1 /* [CP] Embed Pods Frameworks */,
E446637427ECD101CAACE52B /* [CP] Copy Pods Resources */,
+ 20C82871DF97B61FA303C9C9 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@@ -438,12 +512,16 @@
83CBB9F71A601CBA00E9B192 /* Project object */ = {
isa = PBXProject;
attributes = {
+ LastSwiftUpdateCheck = 1510;
LastUpgradeCheck = 1210;
ORGANIZATIONNAME = Facebook;
TargetAttributes = {
13B07F861A680F5B00A75B9A = {
LastSwiftMigration = 1430;
};
+ 763DC3712B0F824200D2C0C5 = {
+ CreatedOnToolsVersion = 15.1;
+ };
E7DB209E22B2BA84005AC45F = {
CreatedOnToolsVersion = 10.2.1;
};
@@ -467,6 +545,7 @@
projectRoot = "";
targets = (
13B07F861A680F5B00A75B9A /* RNTester */,
+ 763DC3712B0F824200D2C0C5 /* RNTester-visionOS */,
E7DB209E22B2BA84005AC45F /* RNTesterUnitTests */,
E7DB215222B2F332005AC45F /* RNTesterIntegrationTests */,
);
@@ -485,6 +564,15 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 763DC3702B0F824200D2C0C5 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 763DC3802B0F824400D2C0C5 /* Preview Assets.xcassets in Resources */,
+ 763DC37D2B0F824400D2C0C5 /* Assets.xcassets in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
E7DB209D22B2BA84005AC45F /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@@ -503,6 +591,23 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
+ 010C6668749A96FAD021029C /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-frameworks-${CONFIGURATION}-input-files.xcfilelist",
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
01934C30687B8C926E4F59CD /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -520,38 +625,60 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
- 02B6FEF7E86B613B42F31284 /* [CP] Embed Pods Frameworks */ = {
+ 20C82871DF97B61FA303C9C9 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-frameworks-${CONFIGURATION}-input-files.xcfilelist",
+ "${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+ "${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-frameworks.sh\"\n";
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
- 4F27ACC9DB890B37D6C267F1 /* [CP] Embed Pods Frameworks */ = {
+ 28541C798E9769A525E7C14E /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-RNTester-visionOS-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;
+ };
+ 4E3C3D35C3AFA4B5CE6A544E /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+ "${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-frameworks.sh\"\n";
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
4F76596957F7356516B534CE /* [CP] Check Pods Manifest.lock */ = {
@@ -609,6 +736,26 @@
shellPath = /bin/sh;
shellScript = "set -e\n\nexport PROJECT_ROOT=\"$SRCROOT\"\nexport ENTRY_FILE=\"$SRCROOT/js/RNTesterApp.ios.js\"\nexport SOURCEMAP_FILE=../sourcemap.ios.map\n# export FORCE_BUNDLING=true \n\nWITH_ENVIRONMENT=\"../react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n";
};
+ 763DC38C2B10A42B00D2C0C5 /* Build JS Bundle */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ "$(SRCROOT)/.xcode.env.local",
+ "$(SRCROOT)/.xcode.env",
+ );
+ name = "Build JS Bundle";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "set -e\n\nexport PROJECT_ROOT=\"$SRCROOT\"\nexport ENTRY_FILE=\"$SRCROOT/js/RNTesterApp.ios.js\"\nexport SOURCEMAP_FILE=../sourcemap.ios.map\n# export FORCE_BUNDLING=true \n\nWITH_ENVIRONMENT=\"../react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n";
+ };
79E8BE2B119D4C5CCD2F04B3 /* [RN] Copy Hermes Framework */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -627,21 +774,21 @@
shellPath = /bin/sh;
shellScript = ". ../react-native/sdks/hermes-engine/utils/copy-hermes-xcode.sh\n";
};
- A904658C20543C2EDC217D15 /* [CP] Embed Pods Frameworks */ = {
+ 8634A0D0E14BF96B8A2F986B /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
+ "${PODS_ROOT}/Target Support Files/Pods-RNTester-visionOS/Pods-RNTester-visionOS-resources-${CONFIGURATION}-input-files.xcfilelist",
);
- name = "[CP] Embed Pods Frameworks";
+ name = "[CP] Copy Pods Resources";
outputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+ "${PODS_ROOT}/Target Support Files/Pods-RNTester-visionOS/Pods-RNTester-visionOS-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-frameworks.sh\"\n";
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester-visionOS/Pods-RNTester-visionOS-resources.sh\"\n";
showEnvVarsInLog = 0;
};
ABDE2A52ACD1B95E14790B5E /* [CP] Check Pods Manifest.lock */ = {
@@ -688,6 +835,23 @@
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 */ = {
+ 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";
+ outputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-RNTester-visionOS/Pods-RNTester-visionOS-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester-visionOS/Pods-RNTester-visionOS-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
E446637427ECD101CAACE52B /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -720,6 +884,15 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 763DC36E2B0F824200D2C0C5 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 76E4BB2C2B34932200B02A15 /* AppDelegate.swift in Sources */,
+ 76E4BB282B34909800B02A15 /* App.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
E7DB209B22B2BA84005AC45F /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -816,6 +989,9 @@
);
PRODUCT_BUNDLE_IDENTIFIER = com.meta.RNTester.localDevelopment;
PRODUCT_NAME = RNTester;
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = NO;
+ SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -854,11 +1030,209 @@
);
PRODUCT_BUNDLE_IDENTIFIER = com.meta.RNTester.localDevelopment;
PRODUCT_NAME = RNTester;
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = NO;
+ SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
+ 763DC3822B0F824400D2C0C5 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 22B01F4E0F077250C6C20B54 /* Pods-RNTester-visionOS.debug.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ DEVELOPMENT_ASSET_PATHS = "\"RNTester-visionOS/Preview Content\"";
+ ENABLE_PREVIEWS = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu17;
+ GENERATE_INFOPLIST_FILE = YES;
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"${PODS_ROOT}/Headers/Public\"",
+ "\"${PODS_ROOT}/Headers/Public/DoubleConversion\"",
+ "\"${PODS_ROOT}/Headers/Public/FBLazyVector\"",
+ "\"${PODS_ROOT}/Headers/Public/MyNativeView\"",
+ "\"${PODS_ROOT}/Headers/Public/NativeCxxModuleExample\"",
+ "\"${PODS_ROOT}/Headers/Public/RCT-Folly\"",
+ "\"${PODS_ROOT}/Headers/Public/RCTDeprecation\"",
+ "\"${PODS_ROOT}/Headers/Public/RCTRequired\"",
+ "\"${PODS_ROOT}/Headers/Public/RCTTypeSafety\"",
+ "\"${PODS_ROOT}/Headers/Public/React-Codegen\"",
+ "\"${PODS_ROOT}/Headers/Public/React-Core\"",
+ "\"${PODS_ROOT}/Headers/Public/React-Fabric\"",
+ "\"${PODS_ROOT}/Headers/Public/React-FabricImage\"",
+ "\"${PODS_ROOT}/Headers/Public/React-ImageManager\"",
+ "\"${PODS_ROOT}/Headers/Public/React-Mapbuffer\"",
+ "\"${PODS_ROOT}/Headers/Public/React-NativeModulesApple\"",
+ "\"${PODS_ROOT}/Headers/Public/React-RCTAnimation\"",
+ "\"${PODS_ROOT}/Headers/Public/React-RCTAppDelegate\"",
+ "\"${PODS_ROOT}/Headers/Public/React-RCTBlob\"",
+ "\"${PODS_ROOT}/Headers/Public/React-RCTFabric\"",
+ "\"${PODS_ROOT}/Headers/Public/React-RCTText\"",
+ "\"${PODS_ROOT}/Headers/Public/React-RuntimeApple\"",
+ "\"${PODS_ROOT}/Headers/Public/React-RuntimeCore\"",
+ "\"${PODS_ROOT}/Headers/Public/React-RuntimeHermes\"",
+ "\"${PODS_ROOT}/Headers/Public/React-callinvoker\"",
+ "\"${PODS_ROOT}/Headers/Public/React-cxxreact\"",
+ "\"${PODS_ROOT}/Headers/Public/React-debug\"",
+ "\"${PODS_ROOT}/Headers/Public/React-graphics\"",
+ "\"${PODS_ROOT}/Headers/Public/React-hermes\"",
+ "\"${PODS_ROOT}/Headers/Public/React-jserrorhandler\"",
+ "\"${PODS_ROOT}/Headers/Public/React-jsi\"",
+ "\"${PODS_ROOT}/Headers/Public/React-jsiexecutor\"",
+ "\"${PODS_ROOT}/Headers/Public/React-jsinspector\"",
+ "\"${PODS_ROOT}/Headers/Public/React-logger\"",
+ "\"${PODS_ROOT}/Headers/Public/React-nativeconfig\"",
+ "\"${PODS_ROOT}/Headers/Public/React-perflogger\"",
+ "\"${PODS_ROOT}/Headers/Public/React-rendererdebug\"",
+ "\"${PODS_ROOT}/Headers/Public/React-runtimeexecutor\"",
+ "\"${PODS_ROOT}/Headers/Public/React-runtimescheduler\"",
+ "\"${PODS_ROOT}/Headers/Public/React-utils\"",
+ "\"${PODS_ROOT}/Headers/Public/ReactCommon\"",
+ "\"${PODS_ROOT}/Headers/Public/ReactCommon-Samples\"",
+ "\"${PODS_ROOT}/Headers/Public/ScreenshotManager\"",
+ "\"${PODS_ROOT}/Headers/Public/SocketRocket\"",
+ "\"${PODS_ROOT}/Headers/Private/Yoga\"",
+ "\"${PODS_ROOT}/Headers/Public/Yoga\"",
+ "\"${PODS_ROOT}/Headers/Public/YogaKit\"",
+ "\"${PODS_ROOT}/Headers/Public/fmt\"",
+ "\"${PODS_ROOT}/Headers/Public/glog\"",
+ "\"${PODS_ROOT}/Headers/Public/hermes-engine\"",
+ "\"$(PODS_ROOT)/DoubleConversion\"",
+ "\"$(PODS_ROOT)/boost\"",
+ "\"$(PODS_ROOT)/Headers/Private/React-Core\"",
+ );
+ INFOPLIST_FILE = "$(TARGET_NAME)/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = (
+ /usr/lib/swift,
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MARKETING_VERSION = 1.0;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.meta.RNTester.localDevelopment.RNTester-visionOS";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SUPPORTED_PLATFORMS = "xros xrsimulator";
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_INCLUDE_PATHS = "$(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/YogaKit-visionOS\" \"${PODS_CONFIGURATION_BUILD_DIR}/YogaKit-iOS\"";
+ "SWIFT_INCLUDE_PATHS[arch=*]" = "$(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/YogaKit-visionOS\" \"${PODS_CONFIGURATION_BUILD_DIR}/YogaKit-iOS\"";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2,7";
+ };
+ name = Debug;
+ };
+ 763DC3832B0F824400D2C0C5 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 54DDA3DF154A732E76DCCEE8 /* Pods-RNTester-visionOS.release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_STYLE = Automatic;
+ COPY_PHASE_STRIP = NO;
+ CURRENT_PROJECT_VERSION = 1;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DEVELOPMENT_ASSET_PATHS = "\"RNTester-visionOS/Preview Content\"";
+ ENABLE_PREVIEWS = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu17;
+ GENERATE_INFOPLIST_FILE = YES;
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"${PODS_ROOT}/Headers/Public\"",
+ "\"${PODS_ROOT}/Headers/Public/DoubleConversion\"",
+ "\"${PODS_ROOT}/Headers/Public/FBLazyVector\"",
+ "\"${PODS_ROOT}/Headers/Public/MyNativeView\"",
+ "\"${PODS_ROOT}/Headers/Public/NativeCxxModuleExample\"",
+ "\"${PODS_ROOT}/Headers/Public/RCT-Folly\"",
+ "\"${PODS_ROOT}/Headers/Public/RCTDeprecation\"",
+ "\"${PODS_ROOT}/Headers/Public/RCTRequired\"",
+ "\"${PODS_ROOT}/Headers/Public/RCTTypeSafety\"",
+ "\"${PODS_ROOT}/Headers/Public/React-Codegen\"",
+ "\"${PODS_ROOT}/Headers/Public/React-Core\"",
+ "\"${PODS_ROOT}/Headers/Public/React-Fabric\"",
+ "\"${PODS_ROOT}/Headers/Public/React-FabricImage\"",
+ "\"${PODS_ROOT}/Headers/Public/React-ImageManager\"",
+ "\"${PODS_ROOT}/Headers/Public/React-Mapbuffer\"",
+ "\"${PODS_ROOT}/Headers/Public/React-NativeModulesApple\"",
+ "\"${PODS_ROOT}/Headers/Public/React-RCTAnimation\"",
+ "\"${PODS_ROOT}/Headers/Public/React-RCTAppDelegate\"",
+ "\"${PODS_ROOT}/Headers/Public/React-RCTBlob\"",
+ "\"${PODS_ROOT}/Headers/Public/React-RCTFabric\"",
+ "\"${PODS_ROOT}/Headers/Public/React-RCTText\"",
+ "\"${PODS_ROOT}/Headers/Public/React-RuntimeApple\"",
+ "\"${PODS_ROOT}/Headers/Public/React-RuntimeCore\"",
+ "\"${PODS_ROOT}/Headers/Public/React-RuntimeHermes\"",
+ "\"${PODS_ROOT}/Headers/Public/React-callinvoker\"",
+ "\"${PODS_ROOT}/Headers/Public/React-cxxreact\"",
+ "\"${PODS_ROOT}/Headers/Public/React-debug\"",
+ "\"${PODS_ROOT}/Headers/Public/React-graphics\"",
+ "\"${PODS_ROOT}/Headers/Public/React-hermes\"",
+ "\"${PODS_ROOT}/Headers/Public/React-jserrorhandler\"",
+ "\"${PODS_ROOT}/Headers/Public/React-jsi\"",
+ "\"${PODS_ROOT}/Headers/Public/React-jsiexecutor\"",
+ "\"${PODS_ROOT}/Headers/Public/React-jsinspector\"",
+ "\"${PODS_ROOT}/Headers/Public/React-logger\"",
+ "\"${PODS_ROOT}/Headers/Public/React-nativeconfig\"",
+ "\"${PODS_ROOT}/Headers/Public/React-perflogger\"",
+ "\"${PODS_ROOT}/Headers/Public/React-rendererdebug\"",
+ "\"${PODS_ROOT}/Headers/Public/React-runtimeexecutor\"",
+ "\"${PODS_ROOT}/Headers/Public/React-runtimescheduler\"",
+ "\"${PODS_ROOT}/Headers/Public/React-utils\"",
+ "\"${PODS_ROOT}/Headers/Public/ReactCommon\"",
+ "\"${PODS_ROOT}/Headers/Public/ReactCommon-Samples\"",
+ "\"${PODS_ROOT}/Headers/Public/ScreenshotManager\"",
+ "\"${PODS_ROOT}/Headers/Public/SocketRocket\"",
+ "\"${PODS_ROOT}/Headers/Public/Yoga\"",
+ "\"${PODS_ROOT}/Headers/Public/fmt\"",
+ "\"${PODS_ROOT}/Headers/Public/glog\"",
+ "\"${PODS_ROOT}/Headers/Public/hermes-engine\"",
+ "\"$(PODS_ROOT)/DoubleConversion\"",
+ "\"$(PODS_ROOT)/boost\"",
+ "\"$(PODS_ROOT)/Headers/Private/React-Core\"",
+ "\"${PODS_ROOT}/Headers/Private/Yoga\"",
+ );
+ INFOPLIST_FILE = "$(TARGET_NAME)/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = (
+ /usr/lib/swift,
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MARKETING_VERSION = 1.0;
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.meta.RNTester.localDevelopment.RNTester-visionOS";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SUPPORTED_PLATFORMS = "xros xrsimulator";
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_INCLUDE_PATHS = "$(inherited) \"${PODS_CONFIGURATION_BUILD_DIR}/YogaKit-visionOS\" \"${PODS_CONFIGURATION_BUILD_DIR}/YogaKit-iOS\"";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2,7";
+ };
+ name = Release;
+ };
83CBBA201A601CBA00E9B192 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -949,7 +1323,7 @@
"-lc++",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../react-native";
- SDKROOT = iphoneos;
+ SDKROOT = xros;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
USE_HERMES = true;
WARNING_CFLAGS = (
@@ -957,6 +1331,7 @@
"-Wall",
"-Wno-semicolon-before-method-body",
);
+ XROS_DEPLOYMENT_TARGET = 1.0;
};
name = Debug;
};
@@ -1042,7 +1417,7 @@
"-lc++",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../react-native";
- SDKROOT = iphoneos;
+ SDKROOT = xros;
USE_HERMES = true;
VALIDATE_PRODUCT = YES;
WARNING_CFLAGS = (
@@ -1050,6 +1425,7 @@
"-Wall",
"-Wno-semicolon-before-method-body",
);
+ XROS_DEPLOYMENT_TARGET = 1.0;
};
name = Release;
};
@@ -1087,6 +1463,8 @@
OTHER_SWIFT_FLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = com.meta.RNTesterUnitTests;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = NO;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
@@ -1125,6 +1503,8 @@
OTHER_SWIFT_FLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = com.meta.RNTesterUnitTests;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = NO;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
@@ -1163,6 +1543,8 @@
OTHER_SWIFT_FLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = com.meta.RNTesterIntegrationTests;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = NO;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RNTester.app/RNTester";
};
@@ -1198,6 +1580,8 @@
OTHER_SWIFT_FLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = com.meta.RNTesterIntegrationTests;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = NO;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RNTester.app/RNTester";
};
@@ -1215,6 +1599,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ 763DC3842B0F824400D2C0C5 /* Build configuration list for PBXNativeTarget "RNTester-visionOS" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 763DC3822B0F824400D2C0C5 /* Debug */,
+ 763DC3832B0F824400D2C0C5 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "RNTesterPods" */ = {
isa = XCConfigurationList;
buildConfigurations = (
diff --git a/packages/rn-tester/metro.config.js b/packages/rn-tester/metro.config.js
index 04a0f563992331..04136b91d6b20d 100644
--- a/packages/rn-tester/metro.config.js
+++ b/packages/rn-tester/metro.config.js
@@ -9,6 +9,7 @@
'use strict';
+const {getPlatformResolver} = require('@callstack/out-of-tree-platforms');
const {getDefaultConfig} = require('@react-native/metro-config');
const {mergeConfig} = require('metro-config');
const path = require('path');
@@ -38,6 +39,9 @@ const config = {
extraNodeModules: {
'react-native': path.resolve(__dirname, '../react-native'),
},
+ resolveRequest: getPlatformResolver({
+ platformNameMap: {visionos: '@callstack/react-native-visionos'},
+ }),
},
};
diff --git a/packages/rn-tester/package.json b/packages/rn-tester/package.json
index 0361b6f5262a63..362cbde9100036 100644
--- a/packages/rn-tester/package.json
+++ b/packages/rn-tester/package.json
@@ -27,11 +27,13 @@
"invariant": "^2.2.4",
"nullthrows": "^1.1.1",
"@react-native/oss-library-example": "*",
- "@react-native/popup-menu-android": "0.75.0-main"
+ "@react-native/popup-menu-android": "0.75.0-main",
+ "@callstack/out-of-tree-platforms": "0.75.0-main"
},
"peerDependencies": {
"react": "19.0.0-rc-fb9a90fa48-20240614",
- "react-native": "*"
+ "react-native": "*",
+ "@callstack/react-native-visionos": "*"
},
"codegenConfig": {
"name": "AppSpecs",
diff --git a/scripts/build/config.js b/scripts/build/config.js
index e889eb4d1b7986..bd1926e5d756e5 100644
--- a/scripts/build/config.js
+++ b/scripts/build/config.js
@@ -58,6 +58,10 @@ const buildConfig /*: BuildConfig */ = {
emitTypeScriptDefs: true,
target: 'node',
},
+ 'out-of-tree-platforms': {
+ emitTypeScriptDefs: true,
+ target: 'node',
+ },
},
};
diff --git a/scripts/e2e/verdaccio.yml b/scripts/e2e/verdaccio.yml
index 46e6710856a977..615f7344a80564 100644
--- a/scripts/e2e/verdaccio.yml
+++ b/scripts/e2e/verdaccio.yml
@@ -19,6 +19,10 @@ packages:
'@react-native/*':
access: $all
publish: $all
+ proxy: npmjs
+ '@callstack/*':
+ access: $all
+ publish: $all
'@*/*':
access: $all
publish: $authenticated
diff --git a/scripts/oot-release.js b/scripts/oot-release.js
new file mode 100644
index 00000000000000..21e281e78b148e
--- /dev/null
+++ b/scripts/oot-release.js
@@ -0,0 +1,151 @@
+/**
+ * Based on `scripts/trigger-react-native-release.js` and `set-rn-version.js`
+ *
+ * @format
+ */
+
+'use strict';
+
+const forEachPackage = require('./monorepo/for-each-package');
+const {applyPackageVersions, publishPackage} = require('./npm-utils');
+const updateTemplatePackage = require('./update-template-package');
+const fs = require('fs');
+const path = require('path');
+const {cat, echo, exit} = require('shelljs');
+const yargs = require('yargs');
+
+/**
+ * This script updates core packages to the version of React Native that we are basing on,
+ * updates internal visionOS packages and releases them.
+ */
+if (require.main === module) {
+ let {argv} = yargs
+ .option('v', {
+ alias: 'new-version',
+ type: 'string',
+ describe:
+ 'New version of `@callstack/react-native-visionos` to be released',
+ required: true,
+ })
+ .option('r', {
+ alias: 'react-native-version',
+ type: 'string',
+ describe:
+ 'React Native version that this release is based on. Ex. "0.72.7" or "0.74.0-nightly-20231130-7e5f15b88"',
+ required: true,
+ })
+ .option('t', {
+ alias: 'tag',
+ type: 'string',
+ describe: 'Tag to be used for publishing packages',
+ required: false,
+ })
+ .option('o', {
+ alias: 'one-time-password',
+ type: 'string',
+ describe: 'One time password for npm publish',
+ required: false,
+ });
+
+ releaseOOT(
+ argv.newVersion,
+ argv.reactNativeVersion,
+ argv.oneTimePassword,
+ argv.tag,
+ );
+ exit(0);
+}
+
+function getPackages() {
+ const packages = {};
+ forEachPackage(
+ (packageAbsolutePath, packageRelativePathFromRoot, packageManifest) => {
+ packages[packageManifest.name] = packageRelativePathFromRoot;
+ },
+ {includeReactNative: true},
+ );
+ return packages;
+}
+
+function setPackage(packagePath, version, dependencyVersions) {
+ const originalPackageJson = JSON.parse(cat(`${packagePath}/package.json`));
+ const packageJson =
+ dependencyVersions != null
+ ? applyPackageVersions(originalPackageJson, dependencyVersions)
+ : originalPackageJson;
+
+ packageJson.version = version;
+
+ fs.writeFileSync(
+ `${packagePath}/package.json`,
+ JSON.stringify(packageJson, null, 2),
+ 'utf-8',
+ );
+}
+
+function releaseOOT(
+ newVersion,
+ reactNativeVersion,
+ oneTimePassword,
+ tag = 'latest',
+) {
+ const allPackages = getPackages();
+ const corePackages = Object.keys(allPackages).filter(packageName =>
+ packageName.startsWith('@react-native/'),
+ );
+ const visionOSPackages = Object.keys(allPackages).filter(packageName =>
+ packageName.startsWith('@callstack/'),
+ );
+
+ const corePackagesVersions = corePackages.reduce(
+ (acc, pkg) => ({...acc, [pkg]: reactNativeVersion}),
+ {},
+ );
+
+ // Update `packges/react-native` package.json and all visionOS packages
+ visionOSPackages.forEach(pkg => {
+ echo(`Setting ${pkg} version to ${newVersion} `);
+ setPackage(allPackages[pkg], newVersion, corePackagesVersions);
+ });
+
+ // Update template package.json
+ updateTemplatePackage({
+ 'react-native': reactNativeVersion,
+ ...corePackagesVersions,
+ ...visionOSPackages.reduce((acc, pkg) => ({...acc, [pkg]: newVersion}), {}),
+ });
+ echo(`Updating template and it's dependencies to ${reactNativeVersion}`);
+
+ // Release visionOS packages only if OTP is passed
+ if (!oneTimePassword) {
+ return;
+ }
+
+ const results = visionOSPackages
+ .map(npmPackage => {
+ return path.join(__dirname, '..', allPackages[npmPackage]);
+ })
+ .map(packagePath => {
+ echo(`Releasing ${packagePath}`);
+ const result = publishPackage(packagePath, {
+ tag,
+ otp: oneTimePassword,
+ });
+
+ return result.code;
+ });
+
+ if (results.every(Boolean)) {
+ echo(`Failed to publish ${visionOSPackages.join(', ')} packages to npm`);
+ return exit(1);
+ } else {
+ echo(
+ `Published ${visionOSPackages.join(
+ ', ',
+ )} to npm with version: ${newVersion}`,
+ );
+ return exit(0);
+ }
+}
+
+module.exports = releaseOOT;
diff --git a/yarn.lock b/yarn.lock
index 80a2ceeda3d984..7da0875414bc6e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7246,7 +7246,7 @@ metro-minify-terser@0.80.3:
dependencies:
terser "^5.15.0"
-metro-resolver@0.80.3, metro-resolver@^0.80.3:
+metro-resolver@0.80.3, metro-resolver@^0.80.0, metro-resolver@^0.80.3:
version "0.80.3"
resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.80.3.tgz#f9676508583d81182c7afaabc908254dc928a345"
integrity sha512-zwa0i32rj/TI3NivcvMXHJwTG2gUgo2dXdcnAJlhEKKQvyN+7AfhNdQSlDdDqMQmU7FaLRdeWORnQJbYCrprQQ==