mirror of
https://github.com/XcodesOrg/XcodesApp.git
synced 2026-04-24 14:37:38 +00:00
warning if users download silicon runtime without xcode 26 selected
This commit is contained in:
parent
0bc8e42a9b
commit
2e2b16e759
9 changed files with 64 additions and 49 deletions
|
|
@ -139,7 +139,6 @@
|
||||||
E8DA461125FAF7FB002E85EF /* NotificationsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8DA461025FAF7FB002E85EF /* NotificationsView.swift */; };
|
E8DA461125FAF7FB002E85EF /* NotificationsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8DA461025FAF7FB002E85EF /* NotificationsView.swift */; };
|
||||||
E8E98A9025D8631800EC89A0 /* InstallationStepRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFBC3FF259AC17F00E2A3D8 /* InstallationStepRowView.swift */; };
|
E8E98A9025D8631800EC89A0 /* InstallationStepRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFBC3FF259AC17F00E2A3D8 /* InstallationStepRowView.swift */; };
|
||||||
E8E98A9625D863D700EC89A0 /* InstallationStepDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8E98A9525D863D700EC89A0 /* InstallationStepDetailView.swift */; };
|
E8E98A9625D863D700EC89A0 /* InstallationStepDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8E98A9525D863D700EC89A0 /* InstallationStepDetailView.swift */; };
|
||||||
E8EE58C02E1CC2A50003FA9F /* RuntimeArchitecture.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8EE58BF2E1CC2A50003FA9F /* RuntimeArchitecture.swift */; };
|
|
||||||
E8F44A1E296B4CD7002D6592 /* Path in Frameworks */ = {isa = PBXBuildFile; productRef = E8F44A1D296B4CD7002D6592 /* Path */; };
|
E8F44A1E296B4CD7002D6592 /* Path in Frameworks */ = {isa = PBXBuildFile; productRef = E8F44A1D296B4CD7002D6592 /* Path */; };
|
||||||
E8FA00542B5B109800769CE0 /* com.xcodesorg.xcodesapp.Helper in Copy Helper */ = {isa = PBXBuildFile; fileRef = CA9FF8AE2595967A00E47BAF /* com.xcodesorg.xcodesapp.Helper */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
E8FA00542B5B109800769CE0 /* com.xcodesorg.xcodesapp.Helper in Copy Helper */ = {isa = PBXBuildFile; fileRef = CA9FF8AE2595967A00E47BAF /* com.xcodesorg.xcodesapp.Helper */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
E8FD5727291EE4AC001E004C /* AsyncNetworkService in Frameworks */ = {isa = PBXBuildFile; productRef = E8FD5726291EE4AC001E004C /* AsyncNetworkService */; };
|
E8FD5727291EE4AC001E004C /* AsyncNetworkService in Frameworks */ = {isa = PBXBuildFile; productRef = E8FD5726291EE4AC001E004C /* AsyncNetworkService */; };
|
||||||
|
|
@ -342,7 +341,6 @@
|
||||||
E8D655BF288DD04700A139C2 /* SelectedActionType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectedActionType.swift; sourceTree = "<group>"; };
|
E8D655BF288DD04700A139C2 /* SelectedActionType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectedActionType.swift; sourceTree = "<group>"; };
|
||||||
E8DA461025FAF7FB002E85EF /* NotificationsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsView.swift; sourceTree = "<group>"; };
|
E8DA461025FAF7FB002E85EF /* NotificationsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsView.swift; sourceTree = "<group>"; };
|
||||||
E8E98A9525D863D700EC89A0 /* InstallationStepDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstallationStepDetailView.swift; sourceTree = "<group>"; };
|
E8E98A9525D863D700EC89A0 /* InstallationStepDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstallationStepDetailView.swift; sourceTree = "<group>"; };
|
||||||
E8EE58BF2E1CC2A50003FA9F /* RuntimeArchitecture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuntimeArchitecture.swift; sourceTree = "<group>"; };
|
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
|
@ -660,7 +658,6 @@
|
||||||
E8E98A9425D863B100EC89A0 /* InfoPane */ = {
|
E8E98A9425D863B100EC89A0 /* InfoPane */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
E8EE58BF2E1CC2A50003FA9F /* RuntimeArchitecture.swift */,
|
|
||||||
B0403CEF2AD92D7B00137C09 /* ReleaseNotesView.swift */,
|
B0403CEF2AD92D7B00137C09 /* ReleaseNotesView.swift */,
|
||||||
B0403CF32AD9381D00137C09 /* SDKsView.swift */,
|
B0403CF32AD9381D00137C09 /* SDKsView.swift */,
|
||||||
B0403CF52AD9849E00137C09 /* CompilersView.swift */,
|
B0403CF52AD9849E00137C09 /* CompilersView.swift */,
|
||||||
|
|
@ -938,7 +935,6 @@
|
||||||
53CBAB2C263DCC9100410495 /* XcodesAlert.swift in Sources */,
|
53CBAB2C263DCC9100410495 /* XcodesAlert.swift in Sources */,
|
||||||
332807412CA5EA820036F691 /* SignInSecurityKeyTouchView.swift in Sources */,
|
332807412CA5EA820036F691 /* SignInSecurityKeyTouchView.swift in Sources */,
|
||||||
CA61A6E0259835580008926E /* Xcode.swift in Sources */,
|
CA61A6E0259835580008926E /* Xcode.swift in Sources */,
|
||||||
E8EE58C02E1CC2A50003FA9F /* RuntimeArchitecture.swift in Sources */,
|
|
||||||
CAE4247F259A666100B8B246 /* MainWindow.swift in Sources */,
|
CAE4247F259A666100B8B246 /* MainWindow.swift in Sources */,
|
||||||
CA452BB0259FD9770072DFA4 /* ProgressIndicator.swift in Sources */,
|
CA452BB0259FD9770072DFA4 /* ProgressIndicator.swift in Sources */,
|
||||||
B0403CF02AD92D7B00137C09 /* ReleaseNotesView.swift in Sources */,
|
B0403CF02AD92D7B00137C09 /* ReleaseNotesView.swift in Sources */,
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,22 @@ extension AppState {
|
||||||
// only selected xcodes > 16.1 beta 3 can download runtimes via a xcodebuild -downloadPlatform version
|
// only selected xcodes > 16.1 beta 3 can download runtimes via a xcodebuild -downloadPlatform version
|
||||||
// only Runtimes coming from cryptexDiskImage can be downloaded via xcodebuild
|
// only Runtimes coming from cryptexDiskImage can be downloaded via xcodebuild
|
||||||
if selectedXcode.version > Version(major: 16, minor: 0, patch: 0) {
|
if selectedXcode.version > Version(major: 16, minor: 0, patch: 0) {
|
||||||
downloadRuntimeViaXcodeBuild(runtime: runtime)
|
|
||||||
|
if runtime.architectures?.isAppleSilicon ?? false {
|
||||||
|
if selectedXcode.version > Version(major: 26, minor: 0, patch: 0) {
|
||||||
|
downloadRuntimeViaXcodeBuild(runtime: runtime)
|
||||||
|
} else {
|
||||||
|
// not supported
|
||||||
|
Logger.appState.error("Trying to download a runtime we can't download")
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.presentedAlert = .generic(title: localizeString("Alert.Install.Error.Title"), message: localizeString("Alert.Install.Error.Need.Xcode26"))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
downloadRuntimeViaXcodeBuild(runtime: runtime)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// not supported
|
// not supported
|
||||||
Logger.appState.error("Trying to download a runtime we can't download")
|
Logger.appState.error("Trying to download a runtime we can't download")
|
||||||
|
|
@ -77,7 +92,8 @@ extension AppState {
|
||||||
|
|
||||||
func downloadRuntimeViaXcodeBuild(runtime: DownloadableRuntime) {
|
func downloadRuntimeViaXcodeBuild(runtime: DownloadableRuntime) {
|
||||||
|
|
||||||
let downloadRuntimeTask = Current.shell.downloadRuntime(runtime.platform.shortName, runtime.simulatorVersion.buildUpdate)
|
let downloadRuntimeTask = Current.shell.downloadRuntime(runtime.platform.shortName, runtime.simulatorVersion.buildUpdate, runtime.architectures?.isAppleSilicon ?? false ? Architecture.arm64.rawValue : nil)
|
||||||
|
|
||||||
runtimePublishers[runtime.identifier] = Task { [weak self] in
|
runtimePublishers[runtime.identifier] = Task { [weak self] in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
do {
|
do {
|
||||||
|
|
@ -258,7 +274,10 @@ extension AppState {
|
||||||
}
|
}
|
||||||
|
|
||||||
func coreSimulatorInfo(runtime: DownloadableRuntime) -> CoreSimulatorImage? {
|
func coreSimulatorInfo(runtime: DownloadableRuntime) -> CoreSimulatorImage? {
|
||||||
return installedRuntimes.filter({ $0.runtimeInfo.build == runtime.simulatorVersion.buildUpdate }).first
|
return installedRuntimes.filter({
|
||||||
|
$0.runtimeInfo.build == runtime.simulatorVersion.buildUpdate &&
|
||||||
|
((runtime.architectures ?? []).isEmpty ? true :
|
||||||
|
$0.runtimeInfo.supportedArchitectures == runtime.architectures )}).first
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteRuntime(runtime: DownloadableRuntime) async throws {
|
func deleteRuntime(runtime: DownloadableRuntime) async throws {
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,7 @@ public struct Shell {
|
||||||
return Process.run(unxipPath.url, workingDirectory: url.deletingLastPathComponent(), ["\(url.path)"])
|
return Process.run(unxipPath.url, workingDirectory: url.deletingLastPathComponent(), ["\(url.path)"])
|
||||||
}
|
}
|
||||||
|
|
||||||
public var downloadRuntime: (String, String) -> AsyncThrowingStream<Progress, Error> = { platform, version in
|
public var downloadRuntime: (String, String, String?) -> AsyncThrowingStream<Progress, Error> = { platform, version, architecture in
|
||||||
return AsyncThrowingStream<Progress, Error> { continuation in
|
return AsyncThrowingStream<Progress, Error> { continuation in
|
||||||
Task {
|
Task {
|
||||||
// Assume progress will not have data races, so we manually opt-out isolation checks.
|
// Assume progress will not have data races, so we manually opt-out isolation checks.
|
||||||
|
|
@ -204,7 +204,7 @@ public struct Shell {
|
||||||
progress.kind = .file
|
progress.kind = .file
|
||||||
progress.fileOperationKind = .downloading
|
progress.fileOperationKind = .downloading
|
||||||
|
|
||||||
let process = Process()
|
var process = Process()
|
||||||
let xcodeBuildPath = Path.root.usr.bin.join("xcodebuild").url
|
let xcodeBuildPath = Path.root.usr.bin.join("xcodebuild").url
|
||||||
|
|
||||||
process.executableURL = xcodeBuildPath
|
process.executableURL = xcodeBuildPath
|
||||||
|
|
@ -215,6 +215,13 @@ public struct Shell {
|
||||||
"\(version)"
|
"\(version)"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if let architecture {
|
||||||
|
process.arguments?.append(contentsOf: [
|
||||||
|
"-architectureVariant",
|
||||||
|
"\(architecture)"
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
let stdOutPipe = Pipe()
|
let stdOutPipe = Pipe()
|
||||||
process.standardOutput = stdOutPipe
|
process.standardOutput = stdOutPipe
|
||||||
let stdErrPipe = Pipe()
|
let stdErrPipe = Pipe()
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import XcodesKit
|
||||||
|
|
||||||
struct PlatformsView: View {
|
struct PlatformsView: View {
|
||||||
@EnvironmentObject var appState: AppState
|
@EnvironmentObject var appState: AppState
|
||||||
@AppStorage("selectedRuntimeArchitecture") private var selectedRuntimeArchitecture: RuntimeArchitecture = .arm64
|
@AppStorage("selectedRuntimeArchitecture") private var selectedRuntimeArchitecture: Architecture = .arm64
|
||||||
|
|
||||||
let xcode: Xcode
|
let xcode: Xcode
|
||||||
|
|
||||||
|
|
@ -22,7 +22,7 @@ struct PlatformsView: View {
|
||||||
appState.downloadableRuntimes.filter {
|
appState.downloadableRuntimes.filter {
|
||||||
$0.sdkBuildUpdate?.contains(sdkBuild) ?? false &&
|
$0.sdkBuildUpdate?.contains(sdkBuild) ?? false &&
|
||||||
($0.architectures?.isEmpty ?? true ||
|
($0.architectures?.isEmpty ?? true ||
|
||||||
$0.architectures?.contains(selectedRuntimeArchitecture.rawValue) ?? false)
|
$0.architectures?.contains(selectedRuntimeArchitecture) ?? false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,10 +43,10 @@ struct PlatformsView: View {
|
||||||
} label: {
|
} label: {
|
||||||
switch selectedRuntimeArchitecture {
|
switch selectedRuntimeArchitecture {
|
||||||
case .arm64:
|
case .arm64:
|
||||||
Label(selectedRuntimeArchitecture.displayValue, systemImage: "m4.button.horizontal")
|
Label(selectedRuntimeArchitecture.rawValue, systemImage: "m4.button.horizontal")
|
||||||
.labelStyle(.trailingIcon)
|
.labelStyle(.trailingIcon)
|
||||||
case .x86_64:
|
case .x86_64:
|
||||||
Label(selectedRuntimeArchitecture.displayValue, systemImage: "cpu.fill")
|
Label(selectedRuntimeArchitecture.rawValue, systemImage: "cpu.fill")
|
||||||
.labelStyle(.trailingIcon)
|
.labelStyle(.trailingIcon)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -74,21 +74,21 @@ struct PlatformsView: View {
|
||||||
Text("\(runtime.visibleIdentifier)")
|
Text("\(runtime.visibleIdentifier)")
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
ForEach(runtime.architectures ?? [], id: \.self) { architecture in
|
ForEach(runtime.architectures ?? [], id: \.self) { architecture in
|
||||||
TagView(text: architecture)
|
TagView(text: architecture.rawValue)
|
||||||
}
|
}
|
||||||
pathIfAvailable(xcode: xcode, runtime: runtime)
|
pathIfAvailable(xcode: xcode, runtime: runtime)
|
||||||
|
|
||||||
if runtime.installState == .notInstalled {
|
if runtime.installState == .notInstalled {
|
||||||
// TODO: Update the downloadableRuntimes with the appropriate installState so we don't have to check path awkwardly
|
// TODO: Update the downloadableRuntimes with the appropriate installState so we don't have to check path awkwardly
|
||||||
if appState.runtimeInstallPath(xcode: xcode, runtime: runtime) != nil {
|
if appState.runtimeInstallPath(xcode: xcode, runtime: runtime) != nil {
|
||||||
EmptyView()
|
EmptyView()
|
||||||
} else {
|
} else {
|
||||||
HStack {
|
HStack {
|
||||||
Spacer()
|
Spacer()
|
||||||
DownloadRuntimeButton(runtime: runtime)
|
DownloadRuntimeButton(runtime: runtime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
Text(runtime.downloadFileSizeString)
|
Text(runtime.downloadFileSizeString)
|
||||||
|
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
//
|
|
||||||
// RuntimeArchitecture.swift
|
|
||||||
// Xcodes
|
|
||||||
//
|
|
||||||
// Created by Matt Kiazyk on 2025-07-07.
|
|
||||||
//
|
|
||||||
|
|
||||||
enum RuntimeArchitecture: String, CaseIterable, Identifiable {
|
|
||||||
case arm64
|
|
||||||
case x86_64
|
|
||||||
|
|
||||||
var id: Self { self }
|
|
||||||
|
|
||||||
var displayValue: String {
|
|
||||||
return rawValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2083,6 +2083,17 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Alert.Install.Error.Need.Xcode26" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Apple supports downloading Apple Silicon runtimes only when Xcode 26+ is selected. Please Select and try downloading again or download the universal build."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"Alert.Install.Error.Title" : {
|
"Alert.Install.Error.Title" : {
|
||||||
"comment" : "Install",
|
"comment" : "Install",
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,10 @@ public struct CoreSimulatorImage: Decodable, Identifiable, Equatable {
|
||||||
|
|
||||||
public struct CoreSimulatorRuntimeInfo: Decodable {
|
public struct CoreSimulatorRuntimeInfo: Decodable {
|
||||||
public let build: String
|
public let build: String
|
||||||
|
public let supportedArchitectures: [Architecture]?
|
||||||
|
|
||||||
public init(build: String) {
|
public init(build: String, supportedArchitectures: [Architecture]? = nil) {
|
||||||
self.build = build
|
self.build = build
|
||||||
|
self.supportedArchitectures = supportedArchitectures
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ public struct DownloadableRuntime: Codable, Identifiable, Hashable {
|
||||||
public let category: Category
|
public let category: Category
|
||||||
public let simulatorVersion: SimulatorVersion
|
public let simulatorVersion: SimulatorVersion
|
||||||
public let source: String?
|
public let source: String?
|
||||||
public let architectures: [String]?
|
public let architectures: [Architecture]?
|
||||||
public let dictionaryVersion: Int
|
public let dictionaryVersion: Int
|
||||||
public let contentType: ContentType
|
public let contentType: ContentType
|
||||||
public let platform: Platform
|
public let platform: Platform
|
||||||
|
|
@ -170,6 +170,7 @@ public struct InstalledRuntime: Decodable {
|
||||||
let state: String
|
let state: String
|
||||||
let version: String
|
let version: String
|
||||||
let sizeBytes: Int?
|
let sizeBytes: Int?
|
||||||
|
let supportedArchitectures: [Architecture]?
|
||||||
}
|
}
|
||||||
|
|
||||||
extension InstalledRuntime {
|
extension InstalledRuntime {
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,6 @@ public enum Architecture: String, Codable, Equatable, Hashable, Identifiable {
|
||||||
case arm64 = "arm64"
|
case arm64 = "arm64"
|
||||||
/// The X86\_64 architecture (64-bit Intel)
|
/// The X86\_64 architecture (64-bit Intel)
|
||||||
case x86_64 = "x86_64"
|
case x86_64 = "x86_64"
|
||||||
/// The i386 architecture (32-bit Intel)
|
|
||||||
case i386 = "i386"
|
|
||||||
/// The PowerPC architecture (Motorola)
|
|
||||||
case powerPC = "ppc"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Array where Element == Architecture {
|
extension Array where Element == Architecture {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue