Skip to content

Expose simulator extras (privacy, appearance, status-bar, openurl, push, location, add-media, screenshot, record-video) via maui apple simulator#308

Open
Copilot wants to merge 5 commits into
mainfrom
copilot/expose-simulator-extras-apis
Open

Expose simulator extras (privacy, appearance, status-bar, openurl, push, location, add-media, screenshot, record-video) via maui apple simulator#308
Copilot wants to merge 5 commits into
mainfrom
copilot/expose-simulator-extras-apis

Conversation

Copilot AI commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Exposes 9 new simulator extras commands under maui apple simulator, wrapping the upstream SimulatorService APIs from Xamarin.Apple.Tools.MaciOS:

  • privacy grant|revoke|reset — manage app privacy permissions (location, photos, camera, etc.)
  • appearance get|light|dark — get/set simulator appearance mode
  • status-bar override|clear — override status bar (time, battery, network, etc.)
  • openurl — open a URL in the simulator
  • push — send a push notification via APNs payload JSON
  • location set|clear — set/clear simulated GPS coordinates
  • add-media — add photos/videos to the simulator photo library
  • screenshot — capture simulator screenshot (png/tiff/bmp/gif/jpeg)
  • record-video — record simulator screen (mp4/fmp4)

Changes

  • AppleCommands.cs — 9 new command registrations with full --json support
  • IAppleProvider.cs / AppleProvider.cs — 13 new provider methods delegating to upstream services
  • FakeAppleProvider.cs — test fake with call tracking
  • SimulatorEnumParsing.cs — shared token→enum mappers for privacy services, data networks, cell bars, wifi bars, battery state
  • MauiCliJsonContext.cs — JSON serialization contexts for new response models
  • ErrorCodes.cs — 5 new error codes (E2211–E2215)
  • AppleSimulatorCommandsTests.cs — 93 unit tests covering all commands
  • apple-cli-smoke-test.sh — updated smoke test script

Fixes Applied During Review

  1. appearance refactored to subcommands — changed from appearance <mode> <udid> (positional args) to appearance get|light|dark <udid> (proper subcommands), consistent with all other simulator commands
  2. location set negative longitudeArgument<double> failed to parse -122.009 (System.CommandLine interpreted -1 as option flag). Fixed with Argument<string> + manual double.TryParse using InvariantCulture
  3. record-video JSON signal — now emits {"status":"recording",...} before the blocking wait, so JSON consumers know recording started
  4. TryParseDataNetwork comment — added explanatory comment about + token survival through Normalize()

Local Testing (macOS, iPhone 17 Pro simulator)

All commands tested successfully on a booted simulator:

=== appearance get ===
{ "udid": "55A9D63B-...", "appearance": "light", "action": "get" }

=== appearance dark ===
{ "udid": "55A9D63B-...", "appearance": "dark", "action": "set" }

=== appearance get (verify dark) ===
{ "udid": "55A9D63B-...", "appearance": "dark", "action": "get" }

=== appearance light (restore) ===
{ "udid": "55A9D63B-...", "appearance": "light", "action": "set" }

=== openurl ===
{ "udid": "55A9D63B-...", "url": "https://dotnet.microsoft.com", "success": true }

=== location set (negative longitude) ===
{ "udid": "55A9D63B-...", "action": "set", "latitude": 37.3349, "longitude": -122.00902, "success": true }

=== location clear ===
{ "udid": "55A9D63B-...", "action": "clear", "success": true }

=== status-bar override --time "9:41" ===
{ "udid": "55A9D63B-...", "action": "override", "success": true }

=== status-bar clear ===
{ "udid": "55A9D63B-...", "action": "clear", "success": true }

=== screenshot (png, 363KB) ===
{ "udid": "55A9D63B-...", "output_path": "/tmp/sim_screenshot.png", "format": "png", "success": true }

Unit Tests

93/93 tests passing:

dotnet test src/Cli/Microsoft.Maui.Cli.UnitTests/ --filter "FullyQualifiedName~AppleSimulatorCommands"
Passed! - Failed: 0, Passed: 93, Skipped: 0

Copilot AI changed the title [WIP] Expose simulator extras via new SimulatorService APIs Expose simulator extras (privacy, appearance, status-bar, openurl, push, location, add-media, screenshot, record-video) via maui apple simulator Jun 3, 2026
Copilot AI requested a review from rmarinho June 3, 2026 01:32
@rmarinho rmarinho marked this pull request as ready for review June 9, 2026 17:40
Copilot AI review requested due to automatic review settings June 9, 2026 17:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds new “simulator extras” commands under maui apple simulator, exposing additional xcrun simctl-backed functionality via Xamarin.Apple.Tools.MaciOS and extending JSON output + tests accordingly.

Changes:

  • Adds 9 new maui apple simulator subcommands (privacy, appearance, status-bar, openurl, push, location, add-media, screenshot, record-video).
  • Extends IAppleProvider/AppleProvider and introduces shared enum/token parsing for simulator-related options.
  • Adds JSON output models + source-gen context registrations and expands unit/smoke-test coverage.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/Cli/Microsoft.Maui.Cli/Providers/Apple/SimulatorEnumParsing.cs New shared token→enum parsing helpers for simulator commands.
src/Cli/Microsoft.Maui.Cli/Providers/Apple/IAppleProvider.cs Extends provider interface with simulator extras operations.
src/Cli/Microsoft.Maui.Cli/Providers/Apple/AppleProvider.cs Implements new simulator extras operations via SimulatorService.
src/Cli/Microsoft.Maui.Cli/Output/MauiCliJsonContext.cs Registers new simulator extras JSON models for source-gen serialization.
src/Cli/Microsoft.Maui.Cli/Output/JsonOutputModels.cs Adds JSON result records for new simulator extras commands.
src/Cli/Microsoft.Maui.Cli/Errors/ErrorCodes.cs Adds new error codes for simulator extras failures.
src/Cli/Microsoft.Maui.Cli/DevFlow/DevFlowCommands.cs Updates DevFlow permission flow to use shared parsing + provider privacy API.
src/Cli/Microsoft.Maui.Cli/Commands/AppleCommands.cs Adds command handlers for simulator extras subcommands.
src/Cli/Microsoft.Maui.Cli.UnitTests/Fakes/FakeAppleProvider.cs Extends test fake with new APIs + call tracking.
src/Cli/Microsoft.Maui.Cli.UnitTests/AppleSimulatorCommandsTests.cs Adds unit coverage for command tree, parsing, JSON models, and handler behavior.
plugins/dotnet-maui/skills/maui-devflow-debug/references/ios-and-mac.md Documents new maui apple simulator … wrappers vs raw simctl.
eng/smoke-tests/apple-cli-smoke-test.sh Extends smoke tests to cover new simulator extras commands.

Comment on lines +1389 to +1393
// Emit a "recording started" signal so JSON consumers know we're active.
if (useJson)
formatter.WriteInfo("{\"status\":\"recording\",\"udid\":\"" + udid + "\",\"output_path\":\"" + outputPath.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\"}");
else
formatter.WriteInfo($"Recording simulator '{udid}' to '{outputPath}'. Press Ctrl-C to stop.");
Comment on lines +788 to +790
formatter.Write(new SimulatorPrivacyResult { Udid = udid, Action = action, Service = SimulatorPrivacy.ToSimctlServiceName(permission), BundleIdentifier = bundleId, Success = true });
else
formatter.WriteSuccess($"Permission '{permissionText}' {action}ed on simulator '{udid}'" + (bundleId != null ? $" for {bundleId}." : "."));
Comment on lines +55 to +59
public const string AppleSimulatorPrivacyFailed = "E2215";
public const string AppleSimulatorAppearanceFailed = "E2216";
public const string AppleSimulatorStatusBarFailed = "E2217";
public const string AppleSimulatorOpenUrlFailed = "E2218";
public const string AppleSimulatorPushFailed = "E2219";
Copilot AI and others added 4 commits June 9, 2026 19:23
…o SimulatorService

Co-authored-by: rmarinho <1235097+rmarinho@users.noreply.github.com>
Co-authored-by: rmarinho <1235097+rmarinho@users.noreply.github.com>
…rd-video signal

- Refactor 'appearance' from positional args to proper subcommands (get/light/dark <udid>)
  for consistency with other simulator commands where <udid> is always first
- Fix location set: change Argument<double> to Argument<string> with manual parsing
  to avoid System.CommandLine failing on negative longitude values (e.g. -122.009)
- Emit JSON 'recording started' status before blocking in record-video so consumers
  know recording is active without waiting for Ctrl-C
- Add clarifying comment for '+' token handling in TryParseDataNetwork
- Add AppearanceCommand_HasGetLightDarkSubcommands structural test

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@rmarinho rmarinho force-pushed the copilot/expose-simulator-extras-apis branch from ac216b4 to f95ccd0 Compare June 9, 2026 18:23
{
var udidArg = new Argument<string>("udid") { Description = "Simulator UDID" };
var outputArg = new Argument<string>("output-path") { Description = "Path to write the recorded video to" };
var formatOption = new Option<string?>("--format") { Description = "Video format: mp4 (default), h264, fmp4, gif" };

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This option currently exposes formats that simctl recordVideo no longer accepts. The MacDev wrapper maps RecordingOptions.Format to xcrun simctl io <udid> recordVideo --type=<value>, but current simctl io help only supports recordVideo [--codec=h264|hevc]; it does not accept --type, mp4, fmp4, or gif. As a result, any invocation with --format will cause simctl to exit immediately, while StartRecording() can still return a process handle and this command will wait for Ctrl-C before reporting success.

Can we switch this surface to a --codec h264|hevc option or update the provider/package to emit --codec=... and reject unsupported values? It would also be good to detect early simctl process exit before blocking/reporting success.

- Replace --format with --codec h264|hevc on record-video command
  (modern simctl only accepts --codec, not --type/format)
- Fix recording-started JSON output: use proper typed model instead
  of raw JSON string inside WriteInfo (fixes machine-readable output)
- Fix privacy success message grammar: 'revokeed' → 'revoked',
  'reseted' → 'reset' via explicit past-tense mapping
- Add SimulatorRecordingStartedResult model + JSON context registration
- Add TryParseVideoCodec() for validated codec parsing
- Add tests for codec parsing and record-video --codec option

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CLI: expose simulator extras via new SimulatorService APIs (privacy, appearance, status_bar, openurl, push, location, addmedia, screen capture)

4 participants