Advanced Topics for VS Code for Mobile Targets

Starting from Uno 4.8.26, the Uno Platform solution templates contains the appropriate support to debug Mobile applications. See below for adjusting projects.

Supported Features

Both Source Link and "Sources embedded inside PDB" features are used by Uno Platform and are supported by the extension.

However, only Android includes the .pdb of the referenced assemblies inside debug builds for net6.0. This makes the features unusable for iOS, macOS, and Mac Catalyst, see issue.

This situation should be fixed with net7.0. A workaround for net6 mobile projects is to install Cymbal.

Remote SSH

VS Code can connect to a remote computer (using ssh) to develop and debug projects. Note that all the sources, build and debugging are done on the remote computer, where the Uno Platform extension is being executed.

Logpoints

Logpoints are functionally similar to adding Console.WriteLine but without modifying the sources.

Converting existing projects

Existing Uno Platform projects requires a few simple changes to work properly with multiples TargetFrameworks inside VS Code.

launch.json

You can add a default entry for all mobile targets by adding the following JSON block inside your launch.json.

{
  "name": "Uno Platform Mobile",
  "type": "Uno",
  "request": "launch",
  // any Uno* task will do, this is simply to satisfy vscode requirement when a launch.json is present
  "preLaunchTask": "Uno: net7.0-android | Debug | android-x64"
},

This will ask the Uno debug provider how to build and launch the application. The Target Framework Moniker (TFM) selected in VS Code's status bar, e.g. net7.0-ios, and the target platform, e.g. iossimulator-x64, will be used automatically.

Note

Uno Platform's templates already include this change.

Debugging with the Windows Subsystem for Android

You first need to connect to the Windows Subsystem for Android (WSA) in order to use it for debugging. From the command-line type:

adb connect 127.0.0.1:58526

and you should then be able to see the WSA device inside VSCode. You can also confirm it's connected from the command-line:

$ adb devices -l
List of devices attached
127.0.0.1:58526        device product:windows_arm64 model:Subsystem_for_Android_TM_ device:windows_arm64 transport_id:1

Settings

Unoplatform › Debugger: Exception Options

You can choose to break execution on specific exceptions, either always or if the exception is unhandled.

Note: Those settings do not apply when debugging Windows (WinUI) or macOS (AppKit) application since it use the CoreCLR debugger.

Unoplatform › Debugger › Ios › Mlaunch: Extra Arguments

For example you can add -vvvvv to get more verbosity from mlaunch.

This can be useful if you run into issues deploying your application to an iOS device.

Unoplatform › Debugger › Ios › Mlaunch: Path

By default the version of mlaunch associated with the currently iOS workload will be used to launch application to iOS devices.

You can override the path to the mlaunch tool to be used. For example you could set the path to /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/bin/mlaunch to use the version from the legacy (pre-net6.0) Xamarin.iOS SDK.

This can be useful when a new Xcode is released, requiring an update to mlaunch, while allowing you to use the current stable SDK version for development.

Unoplatform › Debugger › Ios › Simulator: X64

By default the simulators are listed for both arm64 and x64 on Apple Silicon Macs. x64 simulators are provided using Rosetta emulation and is required if arm64 support is missing for some dependencies (e.g. SkiaSharp).

This can be useful if your project has dependencies that are not available yet for the arm64 architecture.

Environment Variables

Xcode override

The Uno extension uses xcrun to find the active Xcode version to use. You can override this version of Xcode by setting the DEVELOPER_DIR environment variable. More information can be found running man xcrun inside the terminal.

Advanced Debugger Configuration

It is possible to create advanced launch.json and tasks.json entries if additional customization is needed for a project.

Editing launch.json

The extension provides default launch configurations for supported platforms, without the need to define them inside the launch.json file.

If you need to define launches or modify the defaults then you can can create your own.

  1. Press the Shift+Cmd+P keys to open the Command Palette

  2. Select the Debug: Select and Start Debugging item

  3. Select the Add Configuration... item

  4. Select .NET Custom Launch Configuration for Uno Platform item

  5. This will insert a JSON block that looks like the following:

    {
      "comment1": "// name: unique name for the configuration, can be identical to preLaunchTask",
      "name": "Uno: net6.0-android | Debug | android-x64",
      "comment2": "// type: 'Uno' for mono-based SDK, 'coreclr' for desktop targets",
      "type": "Uno",
      "request": "launch",
      "comment3": "// preLaunchTask format is 'Uno: {tfm} | {config}[ | {rid]}]' where ",
      "comment4": "// * {tfm} is the target framework moniker, e.g. net6.0-ios",
      "comment5": "// * {config} is the build configuration, e.g. 'Debug' or 'Release'",
      "comment6": "// * {rid} is the optional runtime identifier, e.g. 'osx-arm64'",
      "comment7": "// E.g. 'Uno: net6.0-ios | Debug | iossimulator-x64', 'Uno: net6.0 | Debug' for desktop",
      "preLaunchTask": "Uno: net6.0-android | Debug | android-x64"
    },
    
  6. Follow the comments to construct the launch required by your target platform, for example:

    {
      "name": "net7.0-ios | simulator | x64",
      "type": "Uno",
      "request": "launch",
      "preLaunchTask": "Uno: net7.0-ios | Debug | iossimulator-x64"
    },
    

If you follow the Uno: {tfm} | {config}[ | {rid]}] convention then there is no need to add entries inside the tasks.json file, the extension already provides them.

Customizing tasks.json

The extension provides default build tasks for most platforms without the need to define them inside the tasks.json file. If you need to define tasks or something that the default built-in tasks do not provide, you can create your own.

  1. Press the Shift+Cmd+P keys to open the Command Palette.
  2. Select the Tasks: Configure Tasks item.
  3. Pick the Uno: * task that is the closest to your need.
  4. Edit the args section but avoid changing the other values (besides the label) to keep automation working.

See VS Code documentation for more information.

Example

{
  "label": "custom-mac-build",
  "command": "dotnet",
  "type": "process",
  "args": [
    "build",
    "${workspaceFolder}/unoapp/unoapp.csproj",
    "/property:GenerateFullPaths=true",
    "/consoleloggerparameters:NoSummary",
    // specify the target platform - since there's more than one inside the mobile.csproj
    "/property:TargetFramework=net8.0-maccatalyst",
    "/property:RuntimeIdentifier=maccatalyst-arm64",
    "/property:Configuration=Debug",
    // this is to workaround both an OmniSharp limitation and a dotnet issue #21877
    "/property:UnoForceSingleTFM=true"
    // other custom settings that you need
  ],
  "problemMatcher": "$msCompile"
},

Tips

  • Most of the build settings should be done (or changed) inside the .csproj file. This way only a simple dotnet build is needed to create the applications.

  • The easiest way to create a custom task is to look at the build logs and see what is normally provided, by default, to build for a specific target platform.

  • You will also need a custom launch target that will use the label name for it's preLaunchTask.