Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion content/best-practices/platform-file-split-or-not.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ Using platform files:

- `file.ios.ts`
- `file.android.ts`
- `file.windows.ts` (when targeting [Windows](/guide/windows/))

The advent of tree shaking and webpack builds does away with quite a bit of worry in this area however there's a few things to consider here.

## Conditional with tree shaking

When speaking of tree shaking ever since NativeScript 7, you've been able to use `__ANDROID__` or `global.isIOS` and anytime those are used as conditional splits in your code, only the applicable code for the platform that's being built would actually end up in your compiled code alleviating a lot of concern here.
When speaking of tree shaking ever since NativeScript 7, you've been able to use `__ANDROID__`, `__WINDOWS__` or `global.isIOS` and anytime those are used as conditional splits in your code, only the applicable code for the platform that's being built would actually end up in your compiled code alleviating a lot of concern here.

## Future maintenance

Expand Down
52 changes: 51 additions & 1 deletion content/configuration/nativescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default {
id: string = 'com.mycompany.myapp'
```

Controls the Application ID of your app, this setting can be overridden per platform via [ios.id](#ios-id) and [android.id](#android-id).
Controls the Application ID of your app, this setting can be overridden per platform via [ios.id](#ios-id), [android.id](#android-id) and [windows.id](#windows-id).

### main

Expand Down Expand Up @@ -163,6 +163,14 @@ ios: Object = {}

See [iOS Configuration Reference](#ios-configuration-reference)

### windows

```ts
windows: Object = {}
```

See [Windows Configuration Reference](#windows-configuration-reference)

### hooks

```ts
Expand Down Expand Up @@ -508,6 +516,48 @@ ios: {
}
```

## Windows Configuration Reference

::: warning Experimental
The Windows platform is experimental. See [Developing for Windows](/guide/windows/).
:::

### <span>windows.id</span>

```ts
windows.id: string = 'com.mycompany.myapp';
```

Controls the package identity name of your Windows app, this setting overrides the value set in [id](#id). The value is written to the `Name` attribute of the `<Identity>` element in the generated `Package.appxmanifest`, and the CLI uses it to find, install and remove the app package.

### windows.sourceProtect

```ts
windows.sourceProtect: boolean = true;
```

When enabled, **release** builds seal the bundled JavaScript into an encrypted `app.nsbundle` instead of shipping it as plain `.js` files. Defaults to `false`.

This can be overridden per build with `--source-protect` or `--no-source-protect`. The encryption key can be provided with `--source-protect-key-hex <key>` or the `NS_WINDOWS_BUNDLE_KEY` environment variable.

```ts
export default {
// ...
windows: {
sourceProtect: true,
},
} as NativeScriptConfig
```

### windows.phoneProductId / windows.phonePublisherId

```ts
windows.phoneProductId: string = '00000000-0000-0000-0000-000000000000';
windows.phonePublisherId: string = '00000000-0000-0000-0000-000000000000';
```

Values written to the `mp:PhoneIdentity` element of the generated `Package.appxmanifest`. When `phoneProductId` isn't set (or is empty/all zeros), the CLI generates a stable GUID derived from the app id. Can be overridden with `--phone-product-id` and `--phone-publisher-id`.

## Hooks Configuration Reference

```ts
Expand Down
9 changes: 8 additions & 1 deletion content/configuration/vite.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,8 @@ Additional env flags that are passed by the CLI automatically
- `--env.android` - `true` when running on Android
- `--env.ios` - `true` when running on iOS
- `--env.visionos` - `true` when running on visionOS
- `--env.platform=<platform>` - for specifying the platform to use. Can be `android`, `ios`, or `visionos`.
- `--env.windows` - `true` when running on Windows
- `--env.platform=<platform>` - for specifying the platform to use. Can be `android`, `ios`, `visionos`, or `windows`.
- `--env.hmr` - `true` when building with HMR enabled

## Global "magic" variables
Expand Down Expand Up @@ -397,6 +398,12 @@ We define a few useful globally available variables that you can use to alter lo
// we are running on an Apple platform
}
```
- `__WINDOWS__`, `true` when the platform is Windows
```ts
if (__WINDOWS__) {
// we are running on Windows
}
```

::: details The following variables are also defined, but are primarily intended to be used by NativeScript Core internally, or plugins that wish to use these.

Expand Down
10 changes: 9 additions & 1 deletion content/configuration/webpack.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ Additional env flags that are usually passed by the CLI automatically
- `--env.nativescriptLibPath` - path to the currently running CLI's library.
- `--env.android` - `true` when running on android
- `--env.ios` - `true` when running on ios
- `--env.platform=<platform>` - for specifying the platform to use. Can be `android` or `ios`, or a custom platform in the future.
- `--env.visionos` - `true` when running on visionOS
- `--env.windows` - `true` when running on Windows
- `--env.platform=<platform>` - for specifying the platform to use. Can be `android`, `ios`, `visionos`, `windows`, or a custom platform.
- `--env.hmr` - `true` when building with HMR enabled

## Global "magic" variables
Expand All @@ -121,6 +123,12 @@ We define a few useful globally available variables that you can use to alter lo
// we are running on iOS
}
```
- `__WINDOWS__` (also available as `global.isWindows`) - `true` when the platform is Windows
```ts
if (__WINDOWS__) {
// we are running on Windows
}
```

::: details The following variables are also defined, but are primarily intended to be used by NativeScript Core internally, or plugins that wish to use these.

Expand Down
1 change: 1 addition & 0 deletions content/guide/adding-native-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ ns native add java com.company.OtherAwesomeClass
1. You can also manually add native code to [App_Resources](/project-structure/app-resources):
- [Adding Java/Kotlin code to an application](/guide/native-code/android)
- [Adding ObjectiveC/Swift Code to an application](/guide/native-code/ios)
- [Adding Windows native code (C#, C++/WinRT, Win32) to an application](/guide/native-code/windows)
2. Optionally [generate TypeScript types for the added APIs](/guide/native-code/generate-typings)

Additionally, NativeScript also supports Jetpack Compose and SwiftUI through plugins.
Expand Down
2 changes: 2 additions & 0 deletions content/guide/cli-basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ Example output:
| 3 | iPhone 14 Pro | iOS | XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX | Emulator | Connected | Local |
```

On a Windows host, the local machine is also listed as a `Windows` device, which is the target used by `ns run windows` (see [Developing for Windows](/guide/windows/)).

## Setting the default package manager

To set the default package manager that the CLI uses (unless overridden in [nativescript.config.ts](/project-structure/nativescript-config#cli-packagemanager)):
Expand Down
63 changes: 61 additions & 2 deletions content/guide/debugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ contributors:
- rigor789
---

There are multiple ways to debug issues in your apps, starting with the simplest form using `console.logs`. For more complex issues, you may need to use an actual debugger, like Chrome DevTools, XCode developer tools and instruments or the Android Studio developer tools.
There are multiple ways to debug issues in your apps, starting with the simplest form using `console.logs`. For more complex issues, you may need to use an actual debugger, like Chrome DevTools, XCode developer tools and instruments, the Android Studio developer tools or Visual Studio on Windows.

## Console

Expand Down Expand Up @@ -41,7 +41,7 @@ console.timeEnd('myLabel')
To start a Chrome debugging session, run your app in debug mode:

```bash
ns debug android|ios
ns debug android|ios|windows
```

The `ns debug` command builds and deploys the app on a connected device or emulator, in case you have multiple devices available you will need to pick one from a list, or pass in the `--device <id>` from `ns devices`.
Expand Down Expand Up @@ -163,3 +163,62 @@ Since NativeScript follows a standard gradle/android application structure, you
- [Android Studio: Layout Inspector](https://developer.android.com/studio/debug/layout-inspector)
- [Android Studio: view Logcat logs](https://developer.android.com/studio/debug/am-logcat)
- [Androud Studio: Debug your app](https://developer.android.com/studio/debug#startdebug)

## Debugging on Windows

::: warning Experimental
The Windows platform is experimental. See [Developing for Windows](/guide/windows/).
:::

### Chrome DevTools

Start a debug session on the local machine with:

```bash
ns debug windows
```

The command builds, deploys and launches the app with the V8 inspector enabled. Once the inspector is listening, a URL is printed to the console:

```bash
# NativeScript Debugger started #
To start debugging, open the following URL in Chrome:
devtools://devtools/bundled/inspector.html?ws=127.0.0.1:43000
```

Open the printed URL in Google Chrome to attach to the debugger session. The inspector listens on port `43000` (iOS uses `41000` and Android `42000`), or the next free port if `43000` is taken.

Alternatively open `chrome://inspect` in Chrome, click **Configure...**, add `127.0.0.1:43000`, and select the app from the **Remote Target** list. Any other client that speaks the Chrome DevTools Protocol can connect to the same address.

The same options as on the other platforms are supported:

- `--debug-brk` - pauses on the first line of JavaScript until the debugger connects. The app waits up to 30 seconds for a debugger, then continues.
- `--start` - attaches to an app that is already running with the debugger enabled (started with `ns debug windows`), without restarting it.
- `--timeout` - number of seconds the CLI waits for the inspector to start. Default is 60 seconds.

`ns run windows` doesn't start the inspector, use `ns debug windows` instead.

The debugger, console, sources, CPU profiling and memory snapshots are provided by V8's inspector. Network requests made with `@nativescript/core` HTTP APIs are shown in the **Network** tab.

### Console output

`ns run windows` and `ns debug windows` stream the app's console output to your terminal. The output is also written to:

- the debugger output (visible in the Visual Studio **Output** window or [DebugView](https://learn.microsoft.com/sysinternals/downloads/debugview))
- `%LOCALAPPDATA%\Packages\<PackageFamilyName>\LocalState\console.log`

### Crash logs

When the app crashes, the runtime writes diagnostic files to the app's `LocalState` folder (`%LOCALAPPDATA%\Packages\<PackageFamilyName>\LocalState\`):

- `nativescript-crash.log` &mdash; unhandled JavaScript and XAML errors (also streamed to the terminal)
- `nativescript-panic.log` &mdash; internal runtime errors
- `nativescript-veh.log` &mdash; fatal native exceptions

In debug builds, an uncaught JavaScript error during startup shows a **NativeScript Runtime Error** dialog with the error details and the option to copy them or restart the app.

Some XAML errors terminate the process immediately (for example error `0xC000027B`) without reaching these logs. In that case check **Event Viewer › Windows Logs › Application**, or capture a crash dump with [ProcDump](https://learn.microsoft.com/sysinternals/downloads/procdump). See [Troubleshooting › Windows](/troubleshooting#windows).

### Debugging native code with Visual Studio

To debug native (C#, C++ or WinRT) code, run the app with `ns run windows`, then in [Visual Studio](https://visualstudio.microsoft.com/) use **Debug › Attach to Process...**, select your app's process, and choose the **Managed** and/or **Native** code types. You can also open the generated host project in `platforms/windows/<ProjectName>/` in Visual Studio to browse and set breakpoints in its code.
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
---
title: Extending WinRT classes and implementing interfaces
description: Subclass Windows Runtime classes and implement WinRT interfaces from JavaScript.
contributors:
- triniwiz
---

::: warning Experimental
Subclassing and interface implementation on Windows are experimental and more limited than on Android and iOS. For most use cases prefer composition (wrapping native controls, as `@nativescript/core` does), or implement the native part in [C# or C++/WinRT](/guide/native-code/windows) and call it from JavaScript.
:::

On Windows, extending a native class or implementing a native interface creates a real .NET type behind the scenes. That type forwards the members you override to your JavaScript implementation, while all other members keep their native behavior.

## Implementing WinRT interfaces

Use `Object.extend` with an `interfaces` list, and implement the interface members using their WinRT names:

```ts
const Stringable = Object.extend({
interfaces: [Windows.Foundation.IStringable],
ToString() {
return 'Hello from JavaScript'
},
})

const instance = new Stringable()
console.log(instance.ToString()) // Hello from JavaScript
```

Multiple interfaces can be listed, and all of their members implemented in the same object.

## Extending WinRT classes

Call `extend` on the base class and pass the members to override. An optional name can be passed as the first argument:

```ts
const MyClass = SomeNamespace.SomeUnsealedClass.extend('MyClass', {
init() {
// called after the instance is constructed
},
SomeVirtualMethod(arg) {
// override
},
})

const instance = new MyClass()
```

- Only the members listed in the overrides object are overridden, all other members use the base implementation.
- `init(...args)` is called after the instance is constructed, with the constructor arguments.
- Getters and setters in the overrides object override the corresponding WinRT properties.

::: warning Sealed classes
Only classes that can be derived from (unsealed, "composable" classes) can be extended. Most WinRT runtime classes, for example `Windows.Data.Json.JsonObject`, are **sealed**. Overrides passed to `extend` on a sealed class have no effect.
:::

### Using TypeScript classes

With TypeScript, decorate a class that extends a WinRT class with `@NativeClass()`, and optionally with the `@Interfaces` and `@CSharpProxy` decorators:

```ts
@NativeClass()
@Interfaces([Windows.Foundation.IStringable])
@CSharpProxy('MyApp.Native.MyStringable')
class MyStringable extends SomeNamespace.SomeUnsealedClass {
ToString() {
return 'MyStringable'
}
}
```

- `@Interfaces([...])` lists the interfaces implemented by the class.
- `@CSharpProxy(name)` sets the full name of the generated .NET type.

::: tip Note
As on Android and iOS, `@NativeClass()` makes sure the class is compiled in a way the runtime can intercept. See [the NativeClass decorator](/best-practices/native-class).
:::

## How it works

At build time the CLI scans your bundled JavaScript for `extend` calls and decorated classes, and generates matching C# proxy types that are compiled into the app. This is similar to the static binding generator used on Android.

In development builds, types that weren't found at build time are generated at runtime instead.

## Limitations

- Sealed classes can't be extended.
- JavaScript overrides are only called on the UI thread, see [Multithreading](/guide/multithreading#windows).
7 changes: 4 additions & 3 deletions content/guide/marshalling/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
title: Marshalling in NativeScript
---

Marshalling in NativeScript refers to the conversion of JavaScript data types to native platform language (Swift/Objective C and Kotlin/Java) data types and vice versa.
Marshalling in NativeScript refers to the conversion of JavaScript data types to native platform language (Swift/Objective C, Kotlin/Java and Windows Runtime) data types and vice versa.

The conversion is handled implicitly by the NativeScript iOS and Android runtimes.
The conversion is handled implicitly by the NativeScript iOS, Android and Windows runtimes.

For more information about how NativeScript converts data types for each platform, read the following articles:

- [iOS Marshalling](/guide/ios-marshalling)
- [Android Marshalling](/guide/android-marshalling)
- [Android Marshalling](/guide/android-marshalling)
- [Windows Marshalling](/guide/windows-marshalling)
23 changes: 23 additions & 0 deletions content/guide/metadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,26 @@ if (android.os.Build.VERSION.SDK_INT >= 21) {
## iOS Metadata

This is our own custom data format for listing the iOS APIs we are aware of and can handle. It stores the minimal required information and provides a small size and highly efficient read access. iOS supports type introspection to some extent but along with the C APIs embedded all the way in the native APIs we had to store a lot of extra information. The Metadata is pre-generated at compile time from the SDK header files and embedded in the app package (ipa).

## Windows Metadata

::: warning Experimental
The Windows platform is experimental. See [Developing for Windows](/guide/windows/).
:::

Unlike iOS and Android, Windows doesn't need metadata to be generated at build time. The Windows Runtime describes every API in `.winmd` metadata files, which the NativeScript Windows runtime reads on demand while the app is running:

- The system `Windows.*` APIs are resolved from the metadata that ships with Windows.
- `Microsoft.*` (WinUI 3 and the Windows App SDK) is resolved from the Windows App SDK the app depends on.
- Any other `.winmd` file placed next to the app executable or in the app root is loaded automatically on startup. See [Adding C++/WinRT components](/guide/native-code/windows#adding-c-winrt-components).

As a result there are no metadata filtering rules on Windows: every WinRT API available on the machine running the app can be called.

::: tip Inspecting a type
To see what the runtime knows about a type, call `__nsDescribeWinRTType` with its full name. It returns a JSON description of the type's methods and properties:

```ts
console.log(__nsDescribeWinRTType('Windows.Foundation.Uri'))
```

:::
14 changes: 14 additions & 0 deletions content/guide/multithreading.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,3 +360,17 @@ There are certain limitations to keep in mind when working with workers:
- **No object transferring**. If you are a web developer you may be familiar with the ArrayBuffer and MessagePort transferring support in browsers. Currently, in NativeScript there is no such concept as object transferring.
- **Debugging workers is not currently possible.**
- **No nested workers support**. We want to hear from the community if this is something we need to support.

## Windows

::: warning Experimental
The Windows platform is experimental. See [Developing for Windows](/guide/windows/).
:::

On Windows, JavaScript runs on the WinUI UI thread, so WinRT and XAML APIs are called directly without any thread marshalling. Each worker runs in its own thread with its own JavaScript runtime and has access to the WinRT APIs (but not to XAML/UI).

Keep the following in mind:

- Messages are serialized using the structured clone algorithm, so values such as `Date`, `Map`, `Set`, `ArrayBuffer` and typed arrays can be sent. Native (WinRT) objects can't be sent.
- JavaScript callbacks only run on the thread that created them. If WinRT invokes a callback (event handler, delegate or async completion) on a background thread, it is not delivered to JavaScript. Subscribe to events and await async operations on the thread that uses the results.
- To get results from a worker back to the UI, `postMessage` them to the main thread. `Utils.isMainThread()` tells you whether the current code runs on the UI thread.
Loading
Loading