Skip to content

Commit 2e2b16e

Browse files
committed
warning if users download silicon runtime without xcode 26 selected
1 parent 0bc8e42 commit 2e2b16e

9 files changed

Lines changed: 64 additions & 49 deletions

File tree

Xcodes.xcodeproj/project.pbxproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@
139139
E8DA461125FAF7FB002E85EF /* NotificationsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8DA461025FAF7FB002E85EF /* NotificationsView.swift */; };
140140
E8E98A9025D8631800EC89A0 /* InstallationStepRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFBC3FF259AC17F00E2A3D8 /* InstallationStepRowView.swift */; };
141141
E8E98A9625D863D700EC89A0 /* InstallationStepDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8E98A9525D863D700EC89A0 /* InstallationStepDetailView.swift */; };
142-
E8EE58C02E1CC2A50003FA9F /* RuntimeArchitecture.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8EE58BF2E1CC2A50003FA9F /* RuntimeArchitecture.swift */; };
143142
E8F44A1E296B4CD7002D6592 /* Path in Frameworks */ = {isa = PBXBuildFile; productRef = E8F44A1D296B4CD7002D6592 /* Path */; };
144143
E8FA00542B5B109800769CE0 /* com.xcodesorg.xcodesapp.Helper in Copy Helper */ = {isa = PBXBuildFile; fileRef = CA9FF8AE2595967A00E47BAF /* com.xcodesorg.xcodesapp.Helper */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
145144
E8FD5727291EE4AC001E004C /* AsyncNetworkService in Frameworks */ = {isa = PBXBuildFile; productRef = E8FD5726291EE4AC001E004C /* AsyncNetworkService */; };
@@ -342,7 +341,6 @@
342341
E8D655BF288DD04700A139C2 /* SelectedActionType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectedActionType.swift; sourceTree = "<group>"; };
343342
E8DA461025FAF7FB002E85EF /* NotificationsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsView.swift; sourceTree = "<group>"; };
344343
E8E98A9525D863D700EC89A0 /* InstallationStepDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstallationStepDetailView.swift; sourceTree = "<group>"; };
345-
E8EE58BF2E1CC2A50003FA9F /* RuntimeArchitecture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuntimeArchitecture.swift; sourceTree = "<group>"; };
346344
/* End PBXFileReference section */
347345

348346
/* Begin PBXFrameworksBuildPhase section */
@@ -660,7 +658,6 @@
660658
E8E98A9425D863B100EC89A0 /* InfoPane */ = {
661659
isa = PBXGroup;
662660
children = (
663-
E8EE58BF2E1CC2A50003FA9F /* RuntimeArchitecture.swift */,
664661
B0403CEF2AD92D7B00137C09 /* ReleaseNotesView.swift */,
665662
B0403CF32AD9381D00137C09 /* SDKsView.swift */,
666663
B0403CF52AD9849E00137C09 /* CompilersView.swift */,
@@ -938,7 +935,6 @@
938935
53CBAB2C263DCC9100410495 /* XcodesAlert.swift in Sources */,
939936
332807412CA5EA820036F691 /* SignInSecurityKeyTouchView.swift in Sources */,
940937
CA61A6E0259835580008926E /* Xcode.swift in Sources */,
941-
E8EE58C02E1CC2A50003FA9F /* RuntimeArchitecture.swift in Sources */,
942938
CAE4247F259A666100B8B246 /* MainWindow.swift in Sources */,
943939
CA452BB0259FD9770072DFA4 /* ProgressIndicator.swift in Sources */,
944940
B0403CF02AD92D7B00137C09 /* ReleaseNotesView.swift in Sources */,

Xcodes/Backend/AppState+Runtimes.swift

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,22 @@ extension AppState {
6161
// only selected xcodes > 16.1 beta 3 can download runtimes via a xcodebuild -downloadPlatform version
6262
// only Runtimes coming from cryptexDiskImage can be downloaded via xcodebuild
6363
if selectedXcode.version > Version(major: 16, minor: 0, patch: 0) {
64-
downloadRuntimeViaXcodeBuild(runtime: runtime)
64+
65+
if runtime.architectures?.isAppleSilicon ?? false {
66+
if selectedXcode.version > Version(major: 26, minor: 0, patch: 0) {
67+
downloadRuntimeViaXcodeBuild(runtime: runtime)
68+
} else {
69+
// not supported
70+
Logger.appState.error("Trying to download a runtime we can't download")
71+
DispatchQueue.main.async {
72+
self.presentedAlert = .generic(title: localizeString("Alert.Install.Error.Title"), message: localizeString("Alert.Install.Error.Need.Xcode26"))
73+
}
74+
return
75+
}
76+
77+
} else {
78+
downloadRuntimeViaXcodeBuild(runtime: runtime)
79+
}
6580
} else {
6681
// not supported
6782
Logger.appState.error("Trying to download a runtime we can't download")
@@ -77,7 +92,8 @@ extension AppState {
7792

7893
func downloadRuntimeViaXcodeBuild(runtime: DownloadableRuntime) {
7994

80-
let downloadRuntimeTask = Current.shell.downloadRuntime(runtime.platform.shortName, runtime.simulatorVersion.buildUpdate)
95+
let downloadRuntimeTask = Current.shell.downloadRuntime(runtime.platform.shortName, runtime.simulatorVersion.buildUpdate, runtime.architectures?.isAppleSilicon ?? false ? Architecture.arm64.rawValue : nil)
96+
8197
runtimePublishers[runtime.identifier] = Task { [weak self] in
8298
guard let self = self else { return }
8399
do {
@@ -258,7 +274,10 @@ extension AppState {
258274
}
259275

260276
func coreSimulatorInfo(runtime: DownloadableRuntime) -> CoreSimulatorImage? {
261-
return installedRuntimes.filter({ $0.runtimeInfo.build == runtime.simulatorVersion.buildUpdate }).first
277+
return installedRuntimes.filter({
278+
$0.runtimeInfo.build == runtime.simulatorVersion.buildUpdate &&
279+
((runtime.architectures ?? []).isEmpty ? true :
280+
$0.runtimeInfo.supportedArchitectures == runtime.architectures )}).first
262281
}
263282

264283
func deleteRuntime(runtime: DownloadableRuntime) async throws {

Xcodes/Backend/Environment.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,15 +196,15 @@ public struct Shell {
196196
return Process.run(unxipPath.url, workingDirectory: url.deletingLastPathComponent(), ["\(url.path)"])
197197
}
198198

199-
public var downloadRuntime: (String, String) -> AsyncThrowingStream<Progress, Error> = { platform, version in
199+
public var downloadRuntime: (String, String, String?) -> AsyncThrowingStream<Progress, Error> = { platform, version, architecture in
200200
return AsyncThrowingStream<Progress, Error> { continuation in
201201
Task {
202202
// Assume progress will not have data races, so we manually opt-out isolation checks.
203203
nonisolated(unsafe) var progress = Progress()
204204
progress.kind = .file
205205
progress.fileOperationKind = .downloading
206206

207-
let process = Process()
207+
var process = Process()
208208
let xcodeBuildPath = Path.root.usr.bin.join("xcodebuild").url
209209

210210
process.executableURL = xcodeBuildPath
@@ -215,6 +215,13 @@ public struct Shell {
215215
"\(version)"
216216
]
217217

218+
if let architecture {
219+
process.arguments?.append(contentsOf: [
220+
"-architectureVariant",
221+
"\(architecture)"
222+
])
223+
}
224+
218225
let stdOutPipe = Pipe()
219226
process.standardOutput = stdOutPipe
220227
let stdErrPipe = Pipe()

Xcodes/Frontend/InfoPane/PlatformsView.swift

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import XcodesKit
1111

1212
struct PlatformsView: View {
1313
@EnvironmentObject var appState: AppState
14-
@AppStorage("selectedRuntimeArchitecture") private var selectedRuntimeArchitecture: RuntimeArchitecture = .arm64
14+
@AppStorage("selectedRuntimeArchitecture") private var selectedRuntimeArchitecture: Architecture = .arm64
1515

1616
let xcode: Xcode
1717

@@ -22,7 +22,7 @@ struct PlatformsView: View {
2222
appState.downloadableRuntimes.filter {
2323
$0.sdkBuildUpdate?.contains(sdkBuild) ?? false &&
2424
($0.architectures?.isEmpty ?? true ||
25-
$0.architectures?.contains(selectedRuntimeArchitecture.rawValue) ?? false)
25+
$0.architectures?.contains(selectedRuntimeArchitecture) ?? false)
2626
}
2727
}
2828

@@ -43,10 +43,10 @@ struct PlatformsView: View {
4343
} label: {
4444
switch selectedRuntimeArchitecture {
4545
case .arm64:
46-
Label(selectedRuntimeArchitecture.displayValue, systemImage: "m4.button.horizontal")
46+
Label(selectedRuntimeArchitecture.rawValue, systemImage: "m4.button.horizontal")
4747
.labelStyle(.trailingIcon)
4848
case .x86_64:
49-
Label(selectedRuntimeArchitecture.displayValue, systemImage: "cpu.fill")
49+
Label(selectedRuntimeArchitecture.rawValue, systemImage: "cpu.fill")
5050
.labelStyle(.trailingIcon)
5151
}
5252
}
@@ -74,21 +74,21 @@ struct PlatformsView: View {
7474
Text("\(runtime.visibleIdentifier)")
7575
.font(.headline)
7676
ForEach(runtime.architectures ?? [], id: \.self) { architecture in
77-
TagView(text: architecture)
77+
TagView(text: architecture.rawValue)
7878
}
7979
pathIfAvailable(xcode: xcode, runtime: runtime)
80-
81-
if runtime.installState == .notInstalled {
82-
// TODO: Update the downloadableRuntimes with the appropriate installState so we don't have to check path awkwardly
83-
if appState.runtimeInstallPath(xcode: xcode, runtime: runtime) != nil {
84-
EmptyView()
85-
} else {
86-
HStack {
87-
Spacer()
88-
DownloadRuntimeButton(runtime: runtime)
89-
}
90-
}
91-
}
80+
81+
if runtime.installState == .notInstalled {
82+
// TODO: Update the downloadableRuntimes with the appropriate installState so we don't have to check path awkwardly
83+
if appState.runtimeInstallPath(xcode: xcode, runtime: runtime) != nil {
84+
EmptyView()
85+
} else {
86+
HStack {
87+
Spacer()
88+
DownloadRuntimeButton(runtime: runtime)
89+
}
90+
}
91+
}
9292

9393
Spacer()
9494
Text(runtime.downloadFileSizeString)

Xcodes/Frontend/InfoPane/RuntimeArchitecture.swift

Lines changed: 0 additions & 17 deletions
This file was deleted.

Xcodes/Resources/Localizable.xcstrings

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2083,6 +2083,17 @@
20832083
}
20842084
}
20852085
},
2086+
"Alert.Install.Error.Need.Xcode26" : {
2087+
"extractionState" : "manual",
2088+
"localizations" : {
2089+
"en" : {
2090+
"stringUnit" : {
2091+
"state" : "translated",
2092+
"value" : "Apple supports downloading Apple Silicon runtimes only when Xcode 26+ is selected. Please Select and try downloading again or download the universal build."
2093+
}
2094+
}
2095+
}
2096+
},
20862097
"Alert.Install.Error.Title" : {
20872098
"comment" : "Install",
20882099
"extractionState" : "manual",

Xcodes/XcodesKit/Sources/XcodesKit/Models/Runtimes/CoreSimulatorImage.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@ public struct CoreSimulatorImage: Decodable, Identifiable, Equatable {
3737

3838
public struct CoreSimulatorRuntimeInfo: Decodable {
3939
public let build: String
40+
public let supportedArchitectures: [Architecture]?
4041

41-
public init(build: String) {
42+
public init(build: String, supportedArchitectures: [Architecture]? = nil) {
4243
self.build = build
44+
self.supportedArchitectures = supportedArchitectures
4345
}
4446
}

Xcodes/XcodesKit/Sources/XcodesKit/Models/Runtimes/Runtimes.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public struct DownloadableRuntime: Codable, Identifiable, Hashable {
1212
public let category: Category
1313
public let simulatorVersion: SimulatorVersion
1414
public let source: String?
15-
public let architectures: [String]?
15+
public let architectures: [Architecture]?
1616
public let dictionaryVersion: Int
1717
public let contentType: ContentType
1818
public let platform: Platform
@@ -170,6 +170,7 @@ public struct InstalledRuntime: Decodable {
170170
let state: String
171171
let version: String
172172
let sizeBytes: Int?
173+
let supportedArchitectures: [Architecture]?
173174
}
174175

175176
extension InstalledRuntime {

Xcodes/XcodesKit/Sources/XcodesKit/Models/XcodeReleases/Architecture.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@ public enum Architecture: String, Codable, Equatable, Hashable, Identifiable {
1515
case arm64 = "arm64"
1616
/// The X86\_64 architecture (64-bit Intel)
1717
case x86_64 = "x86_64"
18-
/// The i386 architecture (32-bit Intel)
19-
case i386 = "i386"
20-
/// The PowerPC architecture (Motorola)
21-
case powerPC = "ppc"
2218
}
2319

2420
extension Array where Element == Architecture {

0 commit comments

Comments
 (0)