Add simulator app lifecycle APIs (install/uninstall/launch/terminate/get_app_container)#176
Merged
Merged
Conversation
…terminate/get_app_container) Agent-Logs-Url: https://github.com/dotnet/macios-devtools/sessions/90cfa0ab-cd62-4bbe-b644-991a95ac7a3a Co-authored-by: rmarinho <1235097+rmarinho@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Add simulator app lifecycle APIs for MAUI DevTools CLI
Add simulator app lifecycle APIs (install/uninstall/launch/terminate/get_app_container)
Apr 30, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a first-class post-boot app lifecycle surface to Xamarin.MacDev’s SimulatorService, reducing the need for callers to shell out to xcrun simctl directly.
Changes:
- Added
SimulatorServicelifecycle methods:Install,Uninstall,Launch,Terminate, andGetAppContainer. - Implemented success/failure handling via existing
SimCtl.Run(...)behavior and added informational logging on success. - Added NUnit tests focused on argument validation plus a macOS-only live test for
GetAppContainer’s failure behavior.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| Xamarin.MacDev/SimulatorService.cs | Introduces five new simulator app lifecycle APIs wrapping xcrun simctl subcommands. |
| tests/SimulatorServiceTests.cs | Adds validation-focused NUnit coverage for the new APIs plus one macOS-gated live assertion. |
Comment on lines
+151
to
+163
| public bool Launch (string udid, string bundleIdentifier, params string [] extraArgs) | ||
| { | ||
| if (string.IsNullOrEmpty (udid)) | ||
| throw new ArgumentException ("UDID must not be null or empty.", nameof (udid)); | ||
| if (string.IsNullOrEmpty (bundleIdentifier)) | ||
| throw new ArgumentException ("Bundle identifier must not be null or empty.", nameof (bundleIdentifier)); | ||
|
|
||
| var args = new string [3 + extraArgs.Length]; | ||
| args [0] = "launch"; | ||
| args [1] = udid; | ||
| args [2] = bundleIdentifier; | ||
| Array.Copy (extraArgs, 0, args, 3, extraArgs.Length); | ||
|
|
|
|
||
| string? output; | ||
| if (!string.IsNullOrEmpty (containerType)) | ||
| output = simctl.Run ("get_app_container", udid, bundleIdentifier, containerType!); |
rolfbjarne
approved these changes
May 5, 2026
This was referenced May 5, 2026
jfversluis
pushed a commit
to dotnet/maui-labs
that referenced
this pull request
May 6, 2026
…app lifecycle commands (#231) * bump: Xamarin.Apple.Tools.MaciOS to 1.0.0-preview.1.26255.1 Updates from dotnet/macios-devtools: - Add PDictionary.OpenFile and TryOpenFile methods (#172) - Add simulator app lifecycle APIs (install/uninstall/launch/terminate/get_app_container) (#176) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat(cli): add simulator app lifecycle commands (install/uninstall/launch/terminate/get-app-container) Leverages the new SimulatorService APIs from Xamarin.Apple.Tools.MaciOS 1.0.0-preview.1.26255.1 (dotnet/macios-devtools#176). New commands: - maui apple simulator install <udid> <app-bundle-path> - maui apple simulator uninstall <udid> <bundle-identifier> - maui apple simulator launch <udid> <bundle-identifier> [--args ...] - maui apple simulator terminate <udid> <bundle-identifier> - maui apple simulator get-app-container <udid> <bundle-identifier> [--type app|data|groups] All commands support --json output mode and emit structured error codes (E2209–E2213). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review feedback: fix JSON output, add validation and tests - Fix moderate issue: install command JSON output now emits 'app_path' instead of a misleading 'bundle_identifier' (was just filename) - Make BundleIdentifier nullable with JsonIgnore when null - Add .app extension validation before attempting install - Use InvalidArgument (E1004) for input validation errors vs AppleSimulatorInstallFailed (E2209) for platform failures - Add 18 unit tests covering command registration, fake provider tracking, JSON serialization, and error code correctness Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address review: UDID validation, handler-level tests, smoke tests - Add SimulatorExists() helper that pre-validates UDID against GetSimulators() before calling lifecycle commands (install, uninstall, launch, terminate, get-app-container). Returns E2204 early if the simulator is not found. - Add 3 handler-level tests exercising full CLI argument parsing: - LaunchCommand_ForwardsArgsToProvider: verifies --args tokens are preserved as extraArgs array - InstallCommand_InvalidUdid_ReturnsSimulatorNotFound: verifies E2204 error when UDID doesn't match any simulator - UninstallCommand_ValidUdid_CallsProvider: verifies successful path - Update smoke test script with 3 new tests (8-10) that validate error handling for invalid UDIDs on the new lifecycle commands - Mark AppleSimulatorCommandsTests with [Collection("CLI")] for safe Program.Services mutation in handler-level tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SimulatorServicehad no post-boot app management surface, forcing callers to shell out toxcrun simctldirectly. This adds the five missing lifecycle methods as first-class API.Xamarin.MacDev/SimulatorService.csFive new methods, each validating arguments and logging via
ICustomLogger:Install(udid, appBundlePath)boolsimctl installUninstall(udid, bundleIdentifier)boolsimctl uninstallLaunch(udid, bundleIdentifier, params extraArgs)boolsimctl launchTerminate(udid, bundleIdentifier)boolsimctl terminateGetAppContainer(udid, bundleIdentifier, containerType?)string?simctl get_app_containerLaunchforwards optional extra arguments to the app process.GetAppContaineraccepts an optional container-type selector ("app","data","groups", etc.) and returns the trimmed path ornullon failure.tests/SimulatorServiceTests.csNew test file with argument-validation unit tests for all five methods, plus a macOS-gated live test verifying
GetAppContainerreturnsnullfor a non-existent app.Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
0t3vsblobprodcus362.vsblob.vsassets.io/usr/bin/dotnet dotnet build Xamarin.MacDev.sln(dns block)/usr/bin/dotnet dotnet restore --no-dependencies /home/REDACTED/work/macios-devtools/macios-devtools/Xamarin.MacDev.sln --packages /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/emptyFakeDotnetRoot /p:AllowMissingPrunePackageData=true(dns block)2kmvsblobprodcus39.vsblob.vsassets.io/usr/bin/dotnet dotnet restore --no-dependencies /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/EAFBC6E33F4372D62A064209AA87BA2F/missingpackages_workingdir --packages /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/missingpackages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal --configfile /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/nugetconfig/nuget.config --force(dns block)/usr/bin/dotnet dotnet restore --no-dependencies /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/46EB19D8E6D150879BD3367A72FC2FBC/missingpackages_workingdir --packages /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/missingpackages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal --configfile /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/nugetconfig/nuget.config --force(dns block)4myvsblobprodcus32.vsblob.vsassets.io/usr/bin/dotnet dotnet restore --no-dependencies /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/5A662EEFB2568432D6FDBE7CF1D19C8E/missingpackages_workingdir --packages /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/missingpackages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal --configfile /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/nugetconfig/nuget.config --force(dns block)51yvsblobprodcus36.vsblob.vsassets.io/usr/bin/dotnet dotnet build Xamarin.MacDev.sln(dns block)/usr/bin/dotnet dotnet build Xamarin.MacDev/Xamarin.MacDev.csproj --no-restore(dns block)/usr/bin/dotnet dotnet restore --no-dependencies /home/REDACTED/work/macios-devtools/macios-devtools/Xamarin.MacDev.sln --packages /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/emptyFakeDotnetRoot /p:AllowMissingPrunePackageData=true(dns block)7devsblobprodcus323.vsblob.vsassets.io/usr/bin/dotnet dotnet restore --no-dependencies /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/C31F48A60590A971E376753BAE25D343/missingpackages_workingdir --packages /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/missingpackages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal --configfile /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/nugetconfig/nuget.config --force(dns block)7k6vsblobprodcus337.vsblob.vsassets.io/usr/bin/dotnet dotnet build Xamarin.MacDev.sln(dns block)jd4vsblobprodcus366.vsblob.vsassets.io/usr/bin/dotnet dotnet restore --no-dependencies /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/5707D9CCD3909344C2384588AB311A3D/missingpackages_workingdir --packages /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/missingpackages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal --configfile /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/nugetconfig/nuget.config --force(dns block)kgfvsblobprodcus314.vsblob.vsassets.io/usr/bin/dotnet dotnet restore --no-dependencies /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/5707D9CCD3909344C2384588AB311A3D/missingpackages_workingdir --packages /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/missingpackages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal --configfile /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/nugetconfig/nuget.config --force(dns block)kmuvsblobprodcus389.vsblob.vsassets.io/usr/bin/dotnet dotnet build Xamarin.MacDev.sln(dns block)/usr/bin/dotnet dotnet restore --no-dependencies /home/REDACTED/work/macios-devtools/macios-devtools/Xamarin.MacDev.sln --packages /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/emptyFakeDotnetRoot /p:AllowMissingPrunePackageData=true(dns block)/usr/bin/dotnet dotnet restore --no-dependencies /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/1381A7934071EB35EC16B755076CAB69/missingpackages_workingdir --packages /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/missingpackages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal --configfile /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/nugetconfig/nuget.config --force(dns block)kxqvsblobprodcus376.vsblob.vsassets.io/usr/bin/dotnet dotnet restore --no-dependencies /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/047D30272EE2B8A118836103AA894C89/missingpackages_workingdir --packages /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/missingpackages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal --configfile /tmp/codeql-scratch-05016c733fb84ab0/dbs/csharp/working/nugetconfig/nuget.config --force(dns block)securitytools.pkgs.visualstudio.com/opt/hostedtoolcache/CodeQL/2.25.1/x64/codeql/csharp/tools/linux64/Semmle.Autobuild.CSharp /opt/hostedtoolcache/CodeQL/2.25.1/x64/codeql/csharp/tools/linux64/Semmle.Autobuild.CSharp(dns block)If you need me to access, download, or install something from one of these locations, you can either: