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 933d17ec51500f..fcec1dc447fa43 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -41,6 +41,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/LinkingIOS/React-RCTLinking.podspec b/packages/react-native/Libraries/LinkingIOS/React-RCTLinking.podspec
index 1980093a5c38a1..0ae62c7b7203f3 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 41e345f37a3c09..51b36e665f7ca6 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/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 e3ed34e4ce26f9..17e3bb796cb4b9 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
@@ -692,6 +694,7 @@ - (void)initializeReturnKeyType
- (void)setDefaultInputAccessoryView
{
+#if !TARGET_OS_VISION
UIView *textInputView = self.backedTextInputView;
UIKeyboardType keyboardType = textInputView.keyboardType;
@@ -730,6 +733,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 dda41dbcada269..58a6d3d7ebeb57 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..25338e8c30e22b 100644
--- a/packages/react-native/React/CoreModules/RCTDeviceInfo.mm
+++ b/packages/react-native/React/CoreModules/RCTDeviceInfo.mm
@@ -51,6 +51,8 @@ - (void)initialize
selector:@selector(didReceiveNewContentSizeMultiplier)
name:RCTAccessibilityManagerDidUpdateMultiplierNotification
object:[_moduleRegistry moduleForName:"AccessibilityManager"]];
+
+#if !TARGET_OS_VISION
_currentInterfaceOrientation = [RCTSharedApplication() statusBarOrientation];
@@ -100,7 +102,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,7 +121,8 @@ - (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();
@@ -124,6 +131,10 @@ static BOOL RCTIsIPhoneNotched()
isIPhoneNotched = RCTSharedApplication().keyWindow.safeAreaInsets.top > 20;
});
+ // 20pt is the top safeArea value in non-notched devices
+ isIPhoneNotched = RCTSharedApplication().keyWindow.safeAreaInsets.top > 20;
+ });
+#endif
return isIPhoneNotched;
}
diff --git a/packages/react-native/React/CoreModules/RCTKeyboardObserver.mm b/packages/react-native/React/CoreModules/RCTKeyboardObserver.mm
index 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/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 d19370132b24f0..611d5cc00af5ad 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..6873bfd801c8b8 100644
--- a/packages/react-native/React/Fabric/Mounting/ComponentViews/Modal/RCTFabricModalHostViewController.mm
+++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/Modal/RCTFabricModalHostViewController.mm
@@ -61,6 +61,7 @@ - (BOOL)prefersStatusBarHidden
#if RCT_DEV
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
+#if !TARGET_OS_VISION
UIInterfaceOrientationMask appSupportedOrientationsMask =
[RCTSharedApplication() supportedInterfaceOrientationsForWindow:[RCTSharedApplication() keyWindow]];
if (!(_supportedInterfaceOrientations & appSupportedOrientationsMask)) {
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 ec977be251f081..c464eafa334a2f 100644
--- a/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm
+++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm
@@ -512,6 +512,7 @@ - (void)initializeReturnKeyType
- (void)setDefaultInputAccessoryView
{
+#if !TARGET_OS_VISION
// InputAccessoryView component sets the inputAccessoryView when inputAccessoryViewID exists
if (_backedTextInputView.inputAccessoryViewID) {
if (_backedTextInputView.isFirstResponder) {
@@ -556,6 +557,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/RCTModalHostViewController.m b/packages/react-native/React/Views/RCTModalHostViewController.m
index 50075ffd4847c3..e938f9a0f1af64 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,6 +54,7 @@ - (BOOL)prefersStatusBarHidden
#if RCT_DEV
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
+#if !TARGET_OS_VISION
UIInterfaceOrientationMask appSupportedOrientationsMask =
[RCTSharedApplication() supportedInterfaceOrientationsForWindow:[RCTSharedApplication() keyWindow]];
if (!(_supportedInterfaceOrientations & appSupportedOrientationsMask)) {
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/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 e86a1efda7ffef..a98843e6178a13 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 5114a581036bd2..d1fab39ab964cb 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": "0.75.2",
- "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",
"@react-native-community/cli-platform-android": "14.0.0",
"@react-native-community/cli-platform-ios": "14.0.0",
+ "@react-native-community/cli-platform-apple": "14.0.0",
"@react-native/assets-registry": "0.75.2",
"@react-native/codegen": "0.75.2",
"@react-native/community-cli-plugin": "0.75.2",
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 5ef30a3e77ece2..21e927bc92cecb 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 074a397bf38ad2..dc312ccfbaffe0 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 345603cc7dca91..356427a8c5bff3 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 1dd1c98544adb5..585159dd2fb395 100644
--- a/packages/react-native/scripts/react_native_pods.rb
+++ b/packages/react-native/scripts/react_native_pods.rb
@@ -31,11 +31,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
@@ -130,6 +134,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)
@@ -157,6 +162,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/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 33c71fa1b74357..992d7a6391810c 100644
--- a/packages/rn-tester/Podfile.lock
+++ b/packages/rn-tester/Podfile.lock
@@ -122,7 +122,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/CoreModulesHeaders (0.75.2):
- glog
@@ -139,7 +139,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/Default (0.75.2):
- glog
@@ -155,7 +155,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/DevSupport (0.75.2):
- glog
@@ -173,7 +173,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/RCTActionSheetHeaders (0.75.2):
- glog
@@ -190,7 +190,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/RCTAnimationHeaders (0.75.2):
- glog
@@ -207,7 +207,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/RCTBlobHeaders (0.75.2):
- glog
@@ -224,7 +224,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/RCTImageHeaders (0.75.2):
- glog
@@ -241,7 +241,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/RCTLinkingHeaders (0.75.2):
- glog
@@ -258,7 +258,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/RCTNetworkHeaders (0.75.2):
- glog
@@ -275,7 +275,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/RCTPushNotificationHeaders (0.75.2):
- glog
@@ -292,7 +292,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/RCTSettingsHeaders (0.75.2):
- glog
@@ -309,7 +309,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/RCTTextHeaders (0.75.2):
- glog
@@ -326,7 +326,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/RCTVibrationHeaders (0.75.2):
- glog
@@ -343,7 +343,7 @@ PODS:
- React-perflogger
- React-runtimescheduler
- React-utils
- - SocketRocket (= 0.7.0)
+ - SocketRocket (= 0.7.0.1)
- Yoga
- React-Core/RCTWebSocket (0.75.2):
- glog
@@ -360,7 +360,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 (0.75.2):
- DoubleConversion
@@ -1623,7 +1657,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- - SocketRocket (0.7.0)
+ - SocketRocket (0.7.0.1)
- Yoga (0.0.0)
DEPENDENCIES:
@@ -1682,6 +1716,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`)
@@ -1698,13 +1733,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"
@@ -1811,6 +1842,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:
@@ -1843,6 +1876,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"
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 4a41c6a49e0eb7..5648193cefe506 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": "0.75.2",
- "@react-native/popup-menu-android": "0.75.2"
+ "@react-native/popup-menu-android": "0.75.2",
+ "@callstack/out-of-tree-platforms": "0.75.2"
},
"peerDependencies": {
"react": "18.3.1",
- "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;