Skip to content

Commit 6a6a832

Browse files
feat: visionOS support (#5783)
Co-Authored-By: Nathan Walker <[email protected]>
1 parent 280b10d commit 6a6a832

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1578
-855
lines changed

README.md

+42-21
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<br>
99
</h1>
1010

11-
<h4 align="center">The NativeScript CLI lets you create, build, and deploy <a href="https://docs.nativescript.org/" target="_blank">NativeScript</a>-based apps on iOS and Android devices.</h4>
11+
<h4 align="center">The NativeScript CLI lets you create, build, and deploy <a href="https://docs.nativescript.org/" target="_blank">NativeScript</a> apps.</h4>
1212
</a>
1313
</h4>
1414

@@ -18,30 +18,51 @@
1818

1919
Get it using: `npm install -g nativescript`
2020

21-
* [What is NativeScript](#what-is-nativescript "Quick overview of NativeScript, the JavaScript framework for cross-platform development of native iOS and Android apps")
22-
* [How the NativeScript CLI works](#how-the-nativescript-cli-works "How the CLI works in more detail")
23-
* [Supported Platforms](#supported-platforms "The mobile platforms you can target with NativeScript")
24-
* [System Requirements](#system-requirements "The hardware and software requirements for setting up and working with the NativeScript CLI")
25-
* [Installation](#installation "How to configure and install the NativeScript CLI")
26-
* [Install the NativeScript CLI](#install-the-nativescript-cli)
27-
* [Configure Proxy Usage](#configure-proxy-settings)
28-
* [Quick Start](#quick-start "Get started with the NativeScript CLI")
29-
* [The Commands](#the-commands)
30-
* [Create Project](#create-project)
31-
* [Develop Your Project](#develop-your-project)
32-
* [Build Your Project](#build-your-project)
33-
* [Run Your Project](#run-your-project)
34-
* [Extending the CLI](#extending-the-cli)
35-
* [Troubleshooting](#troubleshooting)
36-
* [How to Contribute](#how-to-contribute)
37-
* [How to Build](#how-to-build)
38-
* [Get Help](#get-help)
39-
* [License](#license)
21+
- [What is NativeScript](#what-is-nativescript)
22+
- [How the NativeScript CLI works](#how-the-nativescript-cli-works)
23+
- [Supported Platforms](#supported-platforms)
24+
- [System Requirements](#system-requirements)
25+
- [Installation](#installation)
26+
- [Install the NativeScript CLI](#install-the-nativescript-cli)
27+
- [Configure Proxy Settings](#configure-proxy-settings)
28+
- [Set Proxy Settings](#set-proxy-settings)
29+
- [Attributes](#attributes)
30+
- [Options](#options)
31+
- [Limitations](#limitations)
32+
- [Display Current Proxy Settings](#display-current-proxy-settings)
33+
- [Clear Proxy Settings](#clear-proxy-settings)
34+
- [Quick Start](#quick-start)
35+
- [The Commands](#the-commands)
36+
- [Create Project](#create-project)
37+
- [Develop Your Project](#develop-your-project)
38+
- [Development with NativeScript](#development-with-nativescript)
39+
- [Development in `app`](#development-in-app)
40+
- [Development in `platforms`](#development-in-platforms)
41+
- [Modifying Configuration Files](#modifying-configuration-files)
42+
- [Modifying Entitlements File (iOS only)](#modifying-entitlements-file-ios-only)
43+
- [Build Your Project](#build-your-project)
44+
- [Run Your Project](#run-your-project)
45+
- [Extending the CLI](#extending-the-cli)
46+
- [Troubleshooting](#troubleshooting)
47+
- [How to Contribute](#how-to-contribute)
48+
- [How to Build](#how-to-build)
49+
- [Get Help](#get-help)
50+
- [License](#license)
4051

4152
What is NativeScript
4253
===
4354

44-
NativeScript is a cross-platform JavaScript framework that lets you develop native iOS and Android apps from a single code base. The framework provides JavaScript access to the native APIs, user interface, and rendering engines of iOS and Android. By using JavaScript or TypeScript, you can create one project that builds into an iOS or Android app with completely native user experience.
55+
NativeScript provides platform APIs directly to the JavaScript runtime (_with strong types_) for a rich TypeScript development experience.
56+
57+
Some popular use cases:
58+
59+
- Building Web, iOS, Android and Vision Pro apps with a shared codebase (aka, cross platform apps)
60+
- Building native platform apps with portable JavaScript skills
61+
- Augmenting JavaScript projects with platform API capabilities
62+
- AndroidTV and Watch development
63+
- watchOS development
64+
- Learning native platforms through JavaScript understanding
65+
- Exploring platform API documentation by trying APIs [directly from a web browser](https://preview.nativescript.org/) without requiring a platform development machine setup.
4566

4667
To learn more about NativeScript, you can check the following resources:
4768

lib/bootstrap.ts

+8
Original file line numberDiff line numberDiff line change
@@ -180,24 +180,32 @@ injector.requireCommand("platform|update", "./commands/update-platform");
180180
injector.requireCommand("run|*all", "./commands/run");
181181
injector.requireCommand("run|ios", "./commands/run");
182182
injector.requireCommand("run|android", "./commands/run");
183+
injector.requireCommand("run|vision", "./commands/run");
184+
injector.requireCommand("run|visionos", "./commands/run");
183185
injector.requireCommand("typings", "./commands/typings");
184186

185187
injector.requireCommand("preview", "./commands/preview");
186188

187189
injector.requireCommand("debug|ios", "./commands/debug");
188190
injector.requireCommand("debug|android", "./commands/debug");
191+
injector.requireCommand("debug|vision", "./commands/debug");
192+
injector.requireCommand("debug|visionos", "./commands/debug");
189193
injector.requireCommand("fonts", "./commands/fonts");
190194

191195
injector.requireCommand("prepare", "./commands/prepare");
192196
injector.requireCommand("build|ios", "./commands/build");
193197
injector.requireCommand("build|android", "./commands/build");
198+
injector.requireCommand("build|vision", "./commands/build");
199+
injector.requireCommand("build|visionos", "./commands/build");
194200
injector.requireCommand("deploy", "./commands/deploy");
195201

196202
injector.require("testExecutionService", "./services/test-execution-service");
197203
injector.requireCommand("dev-test|android", "./commands/test");
198204
injector.requireCommand("dev-test|ios", "./commands/test");
199205
injector.requireCommand("test|android", "./commands/test");
200206
injector.requireCommand("test|ios", "./commands/test");
207+
// injector.requireCommand("test|vision", "./commands/test");
208+
// injector.requireCommand("test|visionos", "./commands/test");
201209
injector.requireCommand("test|init", "./commands/test-init");
202210
injector.requireCommand("dev-generate-help", "./commands/generate-help");
203211

lib/commands/build.ts

+39-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export class BuildIosCommand extends BuildCommandBase implements ICommand {
108108
$platformValidationService: IPlatformValidationService,
109109
$logger: ILogger,
110110
$buildDataService: IBuildDataService,
111-
private $migrateController: IMigrateController
111+
protected $migrateController: IMigrateController
112112
) {
113113
super(
114114
$options,
@@ -221,3 +221,41 @@ export class BuildAndroidCommand extends BuildCommandBase implements ICommand {
221221
}
222222

223223
injector.registerCommand("build|android", BuildAndroidCommand);
224+
225+
export class BuildVisionOsCommand extends BuildIosCommand implements ICommand {
226+
constructor(
227+
protected $options: IOptions,
228+
$errors: IErrors,
229+
$projectData: IProjectData,
230+
$platformsDataService: IPlatformsDataService,
231+
$devicePlatformsConstants: Mobile.IDevicePlatformsConstants,
232+
$buildController: IBuildController,
233+
$platformValidationService: IPlatformValidationService,
234+
$logger: ILogger,
235+
$buildDataService: IBuildDataService,
236+
protected $migrateController: IMigrateController
237+
) {
238+
super(
239+
$options,
240+
$errors,
241+
$projectData,
242+
$platformsDataService,
243+
$devicePlatformsConstants,
244+
$buildController,
245+
$platformValidationService,
246+
$logger,
247+
$buildDataService,
248+
$migrateController
249+
);
250+
}
251+
252+
public async canExecute(args: string[]): Promise<boolean> {
253+
this.$errors.fail(
254+
'Building for "visionOS" platform is not supported via the CLI. Please open the project in Xcode and build it from there.'
255+
);
256+
return false;
257+
}
258+
}
259+
260+
injector.registerCommand("build|vision", BuildVisionOsCommand);
261+
injector.registerCommand("build|visionos", BuildVisionOsCommand);

lib/commands/create-project.ts

+87-13
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ export class CreateProjectCommand implements ICommand {
1515
private static BlankTemplateDescription = "A blank app";
1616
private static BlankTsTemplateKey = "Blank Typescript";
1717
private static BlankTsTemplateDescription = "A blank typescript app";
18+
private static BlankVisionTemplateKey = "visionOS";
19+
private static BlankVisionTemplateDescription = "A visionOS app";
1820
private static HelloWorldTemplateKey = "Hello World";
1921
private static HelloWorldTemplateDescription = "A Hello World app";
2022
private static DrawerTemplateKey = "SideDrawer";
@@ -58,15 +60,43 @@ export class CreateProjectCommand implements ICommand {
5860

5961
let projectName = args[0];
6062
let selectedTemplate: string;
61-
if (this.$options.js) {
62-
selectedTemplate = constants.JAVASCRIPT_NAME;
63-
} else if (this.$options.vue && this.$options.tsc) {
63+
if (
64+
this.$options["vision-ng"] ||
65+
(this.$options.vision && this.$options.ng)
66+
) {
67+
selectedTemplate = constants.RESERVED_TEMPLATE_NAMES["vision-ng"];
68+
} else if (
69+
this.$options["vision-react"] ||
70+
(this.$options.vision && this.$options.react)
71+
) {
72+
selectedTemplate = constants.RESERVED_TEMPLATE_NAMES["vision-react"];
73+
} else if (this.$options["vision-solid"]) {
74+
// note: we don't have solid templates or --solid
75+
selectedTemplate = constants.RESERVED_TEMPLATE_NAMES["vision-solid"];
76+
} else if (
77+
this.$options["vision-svelte"] ||
78+
(this.$options.vision && this.$options.svelte)
79+
) {
80+
selectedTemplate = constants.RESERVED_TEMPLATE_NAMES["vision-svelte"];
81+
} else if (
82+
this.$options["vision-vue"] ||
83+
(this.$options.vision && (this.$options.vue || this.$options.vuejs))
84+
) {
85+
selectedTemplate = constants.RESERVED_TEMPLATE_NAMES["vision-vue"];
86+
} else if (
87+
(this.$options.vue || this.$options.vuejs) &&
88+
this.$options.tsc
89+
) {
6490
selectedTemplate = "@nativescript/template-blank-vue-ts";
91+
} else if (this.$options.vision) {
92+
selectedTemplate = constants.RESERVED_TEMPLATE_NAMES["vision"];
93+
} else if (this.$options.js) {
94+
selectedTemplate = constants.JAVASCRIPT_NAME;
6595
} else if (this.$options.tsc) {
6696
selectedTemplate = constants.TYPESCRIPT_NAME;
6797
} else if (this.$options.ng) {
6898
selectedTemplate = constants.ANGULAR_NAME;
69-
} else if (this.$options.vue) {
99+
} else if (this.$options.vue || this.$options.vuejs) {
70100
selectedTemplate = constants.VUE_NAME;
71101
} else if (this.$options.react) {
72102
selectedTemplate = constants.REACT_NAME;
@@ -262,6 +292,11 @@ can skip this prompt next time using the --template option, or the --ng, --react
262292
value: "@nativescript/template-tab-navigation-ts",
263293
description: CreateProjectCommand.TabsTemplateDescription,
264294
},
295+
{
296+
key: CreateProjectCommand.BlankVisionTemplateKey,
297+
value: "@nativescript/template-hello-world-ts-vision",
298+
description: CreateProjectCommand.BlankVisionTemplateDescription,
299+
},
265300
];
266301

267302
return templates;
@@ -284,6 +319,11 @@ can skip this prompt next time using the --template option, or the --ng, --react
284319
value: "@nativescript/template-tab-navigation-ng",
285320
description: CreateProjectCommand.TabsTemplateDescription,
286321
},
322+
{
323+
key: CreateProjectCommand.BlankVisionTemplateKey,
324+
value: "@nativescript/template-hello-world-ng-vision",
325+
description: CreateProjectCommand.BlankVisionTemplateDescription,
326+
},
287327
];
288328

289329
return templates;
@@ -296,6 +336,11 @@ can skip this prompt next time using the --template option, or the --ng, --react
296336
value: constants.RESERVED_TEMPLATE_NAMES.react,
297337
description: CreateProjectCommand.HelloWorldTemplateDescription,
298338
},
339+
{
340+
key: CreateProjectCommand.BlankVisionTemplateKey,
341+
value: "@nativescript/template-blank-react-vision",
342+
description: CreateProjectCommand.BlankVisionTemplateDescription,
343+
},
299344
];
300345

301346
return templates;
@@ -308,6 +353,11 @@ can skip this prompt next time using the --template option, or the --ng, --react
308353
value: constants.RESERVED_TEMPLATE_NAMES.svelte,
309354
description: CreateProjectCommand.HelloWorldTemplateDescription,
310355
},
356+
{
357+
key: CreateProjectCommand.BlankVisionTemplateKey,
358+
value: "@nativescript/template-blank-svelte-vision",
359+
description: CreateProjectCommand.BlankVisionTemplateDescription,
360+
},
311361
];
312362

313363
return templates;
@@ -335,6 +385,11 @@ can skip this prompt next time using the --template option, or the --ng, --react
335385
value: "@nativescript/template-tab-navigation-vue",
336386
description: CreateProjectCommand.TabsTemplateDescription,
337387
},
388+
{
389+
key: CreateProjectCommand.BlankVisionTemplateKey,
390+
value: "@nativescript/template-blank-vue-vision",
391+
description: CreateProjectCommand.BlankVisionTemplateDescription,
392+
},
338393
];
339394

340395
return templates;
@@ -346,6 +401,33 @@ can skip this prompt next time using the --template option, or the --ng, --react
346401

347402
const greyDollarSign = color.grey("$");
348403
this.$logger.clearScreen();
404+
let runDebugNotes: Array<string> = [];
405+
if (
406+
this.$options.vision ||
407+
this.$options["vision-ng"] ||
408+
this.$options["vision-react"] ||
409+
this.$options["vision-solid"] ||
410+
this.$options["vision-svelte"] ||
411+
this.$options["vision-vue"]
412+
) {
413+
runDebugNotes = [
414+
`Run the project on Vision Pro with:`,
415+
"",
416+
` ${greyDollarSign} ${color.green("ns run visionos --no-hmr")}`,
417+
];
418+
} else {
419+
runDebugNotes = [
420+
`Run the project on multiple devices:`,
421+
"",
422+
` ${greyDollarSign} ${color.green("ns run ios")}`,
423+
` ${greyDollarSign} ${color.green("ns run android")}`,
424+
"",
425+
"Debug the project with Chrome DevTools:",
426+
"",
427+
` ${greyDollarSign} ${color.green("ns debug ios")}`,
428+
` ${greyDollarSign} ${color.green("ns debug android")}`,
429+
];
430+
}
349431
this.$logger.info(
350432
[
351433
[
@@ -358,15 +440,7 @@ can skip this prompt next time using the --template option, or the --ng, --react
358440
`cd ${relativePath}`
359441
)} and then:`,
360442
"",
361-
`Run the project on multiple devices:`,
362-
"",
363-
` ${greyDollarSign} ${color.green("ns run ios")}`,
364-
` ${greyDollarSign} ${color.green("ns run android")}`,
365-
"",
366-
"Debug the project with Chrome DevTools:",
367-
"",
368-
` ${greyDollarSign} ${color.green("ns debug ios")}`,
369-
` ${greyDollarSign} ${color.green("ns debug android")}`,
443+
...runDebugNotes,
370444
``,
371445
`For more options consult the docs or run ${color.green("ns --help")}`,
372446
"",

0 commit comments

Comments
 (0)