Skip to content

fix: collapse duplicate installed runtime rows in Platforms preferences#828

Open
beforeold wants to merge 1 commit into
XcodesOrg:mainfrom
beforeold:fix/duplicate-installed-runtime-rows
Open

fix: collapse duplicate installed runtime rows in Platforms preferences#828
beforeold wants to merge 1 commit into
XcodesOrg:mainfrom
beforeold:fix/duplicate-installed-runtime-rows

Conversation

@beforeold

Copy link
Copy Markdown

Summary

The Platforms preferences screen ("Below are a list of platforms that are installed on this machine.") can show the same installed runtime more than once — most visibly "iOS 26.4 Simulator Runtime" appearing twice with two different sizes (e.g. 10.6 GB and 8.46 GB), even though only one copy is installed on disk.

Root cause

PlatformsListView.loadRuntimes() builds the list from downloadableRuntimes (Apple's downloadable-runtime index) and keeps every record whose simulatorVersion.buildUpdate matches any installed build:

let filteredRuntimes = appState.downloadableRuntimes.filter { runtime in
    appState.installedRuntimes.contains { $0.runtimeInfo.build == runtime.simulatorVersion.buildUpdate }
}

Apple ships multiple downloadable records for the same build — a Universal (arm64 + x86_64) package and an Apple Silicon-only (arm64) package. They share the same name and buildUpdate but differ in identifier and architectures:

name identifier architectures buildUpdate fileSize
iOS 26.4 Simulator Runtime com.apple.dmg.iPhoneSimulatorSDK26_4 [arm64, x86_64] 23E244 10.60 GB
iOS 26.4 Simulator Runtime com.apple.dmg.iPhoneSimulatorSDK26_4_arm64 [arm64] 23E244 8.46 GB

A single installed 23E244 runtime matches both records, so the ForEach(runtimeList, id: \.self) renders two rows (DownloadableRuntime's equality is by identifier, so the two records are not de-duplicated). The two sizes are the two downloads' declared fileSize values, not two on-disk copies.

PlatformsView (the Xcode info pane) is unaffected because it filters to a single architecture variant upstream before display; the preferences list never had that de-duplication.

Fix

Drive the list from the installed runtimes and collapse to one row per installed build, preferring the downloadable variant whose architectures match the installed image's supportedArchitectures. Deletion is unaffected — it already resolves the on-disk image by build via RuntimeInstallationLookupService, not by the exact downloadable identifier.

Testing

Added XcodesTests/PlatformsListViewTests.swift covering:

  • A single installed build with both Universal and arm64 downloadable variants collapses to one row (and picks the arch-matching variant).
  • Distinct installed builds each keep their own row.
  • Runtimes that aren't installed locally are excluded.

Full suite passes locally:

xcodebuild test -scheme Xcodes -destination 'platform=macOS' -only-testing:XcodesTests
Executed 38 tests, with 0 failures

🤖 Generated with Claude Code

The Platforms preferences list mapped each installed simulator runtime to
every downloadable record sharing its build update. Apple's downloadable
runtime index ships multiple records per build (e.g. a Universal and an
Apple Silicon-only variant with the same name and buildUpdate but different
identifier and architectures), so a single installed runtime was rendered as
multiple rows — most visibly "iOS 26.4 Simulator Runtime" appearing twice
with different sizes.

Drive the list from the installed runtimes instead, collapsing to one row
per installed build and preferring the downloadable variant whose
architectures match what is actually installed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.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.

1 participant