Skip to content

feat: support Apple TV, Apple Watch, and Apple Vision Pro simulator slimming - #54

Merged
Interlap01 merged 3 commits into
mainfrom
feat/tvos-watchos-slimming
Oct 8, 2026
Merged

Interlap01 merged 3 commits into
mainfrom
feat/tvos-watchos-slimming

Conversation

@Interlap01

@Interlap01 Interlap01 commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Apple TV, Apple Watch, and Apple Vision Pro simulators were filtered out during discovery, so none of the slimming commands could target them. Discover iOS, tvOS, watchOS, and visionOS devices across all supported device sets and carry platform metadata through JSON, CLI tables, and the macOS app.

  • Apply platform-specific persistence gates (iOS/tvOS 18.5, watchOS 11.5, visionOS 2.5), retaining no-reboot slimming for older runtimes and readback verification after boot. Keep the existing iOS library helper compatible.
  • Keep com.apple.homed enabled on watchOS: the watchOS 26.5 smoke test showed that the system re-enables it after startup. Use the resulting 169-label profile consistently for slimming, verification, status, and app counts.
  • visionOS (feat: support Apple Vision Pro simulator slimming and speed up no-reboot slims #56, @Jeehut): CoreSimulator still names the runtime xrOS, so parseRuntime maps it to visionOS. Keep com.apple.mobileassetd enabled there, because the simulated surroundings are mobile assets; without it the device boots into a black space around the Home View while apps still launch.
  • Faster on --no-reboot (feat: support Apple Vision Pro simulator slimming and speed up no-reboot slims #56): one launchctl unload -w per 64 job plists stops most labels at once. A plist is used only when its own Label matches, and the state is read back so anything the batch missed takes the existing per-label disable + bootout path.
  • Follow-up: the batch reuses the device EnableSlimNoReboot already resolved instead of listing devices again, and the --no-reboot help names the visionOS cutoff.
  • Reject clone repair between different platforms even when their version numbers match. Document platform behavior and keep iOS memory measurements clearly scoped.

Validation:

  • make check passes (Go tests/vet, Swift formatting, shell syntax, plist validation), locally and in CI.
  • make app and codesign --verify --deep --strict pass.
  • Disposable watchOS 26.5 simulator: persistent slimming, verification after a separate shutdown/boot, restoration to stock, and no-reboot slimming with 169/169 overrides verified. Test device removed afterward.
  • Final branch head on real simulators: tvOS 27.0 on --no-reboot stopped 86/170 services in one batch and verified slim (170/170); a rerun took 3 s and reported everything already stopped. watchOS 27.0 batched 100/169 and verified slim (169/169). Both restored with off.
  • visionOS 27.0 was tested in feat: support Apple Vision Pro simulator slimming and speed up no-reboot slims #56: slim at 88 processes and ~1.2 GB (vs 218 processes and 2.8 GB stock), 60 fps, surroundings intact, profile kept across reboot, off restores stock.
  • Regression tests cover mixed-platform discovery and device-set routing, JSON metadata, version boundaries, slim/restore/idempotence, old-runtime no-reboot behavior, lost overrides, the Watch and visionOS service exceptions, batch unload fallbacks, and cross-platform clone rejection.

The tvOS 18.5, watchOS 11.5, and visionOS 2.5 persistence cutoffs follow the corresponding iOS release generation; those earliest runtimes have not been independently smoke-tested. Every platform retains post-boot override verification.

@Jeehut

Jeehut commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Thank you for this PR! The Device.Platform structure made adding visionOS on top of it really easy. 🙏

Your validation covers watchOS on a real simulator, so I had the tvOS side checked as well. A tvOS 27.0 simulator slimmed with this branch boots to the normal Home screen. The Siri Remote still moves focus and selects inside an app, and the app still sees the remote as a game controller, even though gamecontrollerd is disabled. It ran with about half the processes and 35 to 57 % less memory across two separate runs, at 60 fps. A reboot keeps the profile, and off brings it back to stock.

I opened #56 on top of your branch. It adds visionOS support and a faster on --no-reboot.

Jeehut and others added 2 commits October 8, 2026 12:04
…oot slims (#56)

* perf: stop a no-reboot slim's daemons with one launchctl spawn

`on --no-reboot` runs a `launchctl disable` and a `launchctl bootout`
spawn per label, 340 spawns for the full 170-label profile. A spawn is
cheap on a quiet Mac but can take seconds on a host busy with other
simulators and builds, and a live slim then needs minutes.

`launchctl unload -w` takes many job plists at once: it writes the same
persistent disable override as `disable` and removes the loaded job
like `bootout`. Simulator processes see the host file system, so the
plists under the runtime's RuntimeRoot can be passed by path, in chunks
of 64. `Device` now carries its `RuntimeID` to find that RuntimeRoot.

A plist is only used when its own `Label` key matches the label, so a
misnamed file can never unload a daemon outside the allowlist. The state
is read back afterwards (`print-disabled` and `launchctl list`), and
anything still enabled or loaded takes the existing per-label path. A
chunk that outlasts its spawn timeout ends the batch, so a slow host
keeps its remaining budget for that path.

* feat: support Apple Vision Pro simulator slimming

Builds on the Apple TV and Apple Watch support: CoreSimulator names the
visionOS runtime `xrOS`, so `parseRuntime` now maps it to the `visionOS`
platform, and every command, the JSON output, and the macOS app pick it
up through the existing platform plumbing.

**visionOS keeps `com.apple.mobileassetd` enabled.** The simulated
surroundings and the Home View are mobile assets. With mobileassetd
disabled a visionOS 27.0 simulator boots to a black space with no Home
View, while apps still launch, so a boot check alone does not notice it.
`desiredForDevice` skips it like homed on watchOS, so slimming,
verification, status totals, and the app's count agree, and a device
slimmed before this exception gets the service back on its next `on`.

**Persistence gate.** visionOS 2.5 is the release generation of iOS
18.5, following the tvOS and watchOS cutoffs. Like those, it is not an
independent measurement; every platform is still read back after boot.
…S no-reboot cutoff

EnableSlimNoReboot already resolves the device, so unloadInBatch takes its
RuntimeID instead of running a second simctl list. listDevicesInSet sets
RuntimeID in its main loop, and the --no-reboot help names visionOS < 2.5.
@Interlap01
Interlap01 merged commit 867e276 into main Oct 8, 2026
1 check passed
@Interlap01 Interlap01 changed the title feat: support Apple TV and Apple Watch simulator slimming feat: support Apple TV, Apple Watch, and Apple Vision Pro simulator slimming Oct 8, 2026
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.

2 participants