Summary
Add the remaining xcrun simctl operations to Xamarin.MacDev.SimulatorService so the MAUI DevTools CLI can drive simulator state for tests and demos without shelling out: privacy permissions, appearance, status-bar overrides, deep-link, push notifications, location, media library, and screen capture.
Context
After #149 (basic management) and the upcoming app-lifecycle issue (install/launch/terminate/uninstall), this is the last batch of simctl features that the MAUI DevTools CLI today falls back on raw xcrun simctl for. See maui-labs#197 for the full audit and the active workaround in maui devflow ui permission (which currently bypasses this library).
Proposed API surface
These are independent groups; can land as a single PR or sub-PRs at maintainer preference. Suggest grouping as nested classes under SimulatorService for discoverability.
1. Privacy
public partial class SimulatorService
{
public Privacy PrivacyService { get; }
}
public class Privacy
{
/// xcrun simctl privacy <udid> grant <service> [bundleId]
public bool Grant(string udidOrName, PrivacyService service, string? bundleIdentifier = null);
public bool Revoke(string udidOrName, PrivacyService service, string? bundleIdentifier = null);
public bool Reset(string udidOrName, PrivacyService service, string? bundleIdentifier = null);
}
public enum PrivacyService
{
All, Calendar, ContactsLimited, Contacts, Location, LocationAlways,
PhotosAdd, Photos, MediaLibrary, Microphone, Motion, Reminders, Siri
}
2. Appearance
/// xcrun simctl ui <udid> appearance <light|dark>
public bool SetAppearance(string udidOrName, SimulatorAppearance appearance);
public SimulatorAppearance? GetAppearance(string udidOrName);
public enum SimulatorAppearance { Light, Dark }
3. Status bar override
public StatusBar StatusBarService { get; }
public class StatusBar
{
/// xcrun simctl status_bar <udid> override --time HH:mm --batteryLevel N --dataNetwork wifi ...
public bool Override(string udidOrName, StatusBarOverrides overrides);
public bool Clear(string udidOrName);
}
public record StatusBarOverrides(
string? Time = null,
int? BatteryLevel = null,
BatteryState? BatteryState = null,
DataNetwork? DataNetwork = null,
int? CellularBars = null,
int? WifiBars = null,
string? OperatorName = null);
4. URL / deep-link
/// xcrun simctl openurl <udid> <url>
public bool OpenUrl(string udidOrName, string url);
5. Push notification
/// xcrun simctl push <udid> <bundleId> <payloadFile>
/// or xcrun simctl push <udid> <bundleId> - (stdin)
public bool Push(string udidOrName, string bundleIdentifier, string payloadJsonOrPath);
6. Location
public Location LocationService { get; }
public class Location
{
/// xcrun simctl location <udid> set <lat>,<lon>
public bool Set(string udidOrName, double latitude, double longitude);
/// xcrun simctl location <udid> clear
public bool Clear(string udidOrName);
/// xcrun simctl location <udid> run <gpxPath>
public bool Run(string udidOrName, string gpxPath, double? speed = null, int? interval = null);
}
7. Media library
/// xcrun simctl addmedia <udid> <path1> <path2> ...
public bool AddMedia(string udidOrName, IEnumerable<string> paths);
8. Screen capture
public ScreenCapture ScreenCaptureService { get; }
public class ScreenCapture
{
/// xcrun simctl io <udid> screenshot <outputPath> [--type=png|jpeg]
public bool Screenshot(string udidOrName, string outputPath, ScreenshotFormat format = ScreenshotFormat.Png);
/// xcrun simctl io <udid> recordVideo <outputPath>
/// Returns a handle that the consumer disposes to stop the recording.
public IDisposable StartRecording(string udidOrName, string outputPath, RecordingOptions? options = null);
}
Consumer
- MAUI DevTools CLI (dotnet/maui-labs) — new subcommands under
maui apple simulator: privacy grant|revoke|reset, appearance light|dark, status-bar override|clear, openurl, push, location set|clear|run, add-media, screenshot, recordvideo. See maui-labs#197 audit.
- DevFlow
maui devflow ui permission wrapper currently shells out to xcrun simctl privacy directly with auto-detected UDID and bundle id. Once group 1 (Privacy) lands, that wrapper will be refactored to consume SimulatorService.PrivacyService instead.
- DevFlow integration tests for theme-switching and notification-driven scenarios.
- IDE extensions for "Run with dark mode" / "Send test push" / "Set fake location" debug actions.
Related
Summary
Add the remaining
xcrun simctloperations toXamarin.MacDev.SimulatorServiceso the MAUI DevTools CLI can drive simulator state for tests and demos without shelling out: privacy permissions, appearance, status-bar overrides, deep-link, push notifications, location, media library, and screen capture.Context
After #149 (basic management) and the upcoming app-lifecycle issue (install/launch/terminate/uninstall), this is the last batch of
simctlfeatures that the MAUI DevTools CLI today falls back on rawxcrun simctlfor. See maui-labs#197 for the full audit and the active workaround inmaui devflow ui permission(which currently bypasses this library).Proposed API surface
These are independent groups; can land as a single PR or sub-PRs at maintainer preference. Suggest grouping as nested classes under
SimulatorServicefor discoverability.1. Privacy
2. Appearance
3. Status bar override
4. URL / deep-link
5. Push notification
6. Location
7. Media library
8. Screen capture
Consumer
maui apple simulator:privacy grant|revoke|reset,appearance light|dark,status-bar override|clear,openurl,push,location set|clear|run,add-media,screenshot,recordvideo. See maui-labs#197 audit.maui devflow ui permissionwrapper currently shells out toxcrun simctl privacydirectly with auto-detected UDID and bundle id. Once group 1 (Privacy) lands, that wrapper will be refactored to consumeSimulatorService.PrivacyServiceinstead.Related
maui apple simulator) #149 (closed) — basic simulator managementmaui apple runtime) #150 (closed) — runtime management