Skip to content

Commit a434d26

Browse files
authored
Merge pull request #730 from XcodesOrg/matt/multipleArch
Support Xcode 26 multiple Architectures
2 parents f3f3bf0 + 7861541 commit a434d26

10 files changed

Lines changed: 244 additions & 32 deletions

File tree

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ on:
88

99
jobs:
1010
test:
11-
runs-on: macos-14
11+
runs-on: macos-15
1212
steps:
1313
- uses: actions/checkout@v4
1414
- name: Run tests
1515
env:
16-
DEVELOPER_DIR: /Applications/Xcode_16.app
16+
DEVELOPER_DIR: /Applications/Xcode_16.4.app
1717
run: xcodebuild test -scheme Xcodes

Xcodes.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@
115115
CAFE4AB425B7D3AF0064FE51 /* AdvancedPreferencePane.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFE4AB325B7D3AF0064FE51 /* AdvancedPreferencePane.swift */; };
116116
CAFE4ABC25B7D54B0064FE51 /* UpdatesPreferencePane.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFE4ABB25B7D54B0064FE51 /* UpdatesPreferencePane.swift */; };
117117
CAFFFED8259CDA5000903F81 /* XcodeListViewRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFFFED7259CDA5000903F81 /* XcodeListViewRow.swift */; };
118+
D93F95C12E0C8C1A00238FB5 /* TagView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D93F95C02E0C8C1A00238FB5 /* TagView.swift */; };
118119
E689540325BE8C64000EBCEA /* DockProgress in Frameworks */ = {isa = PBXBuildFile; productRef = E689540225BE8C64000EBCEA /* DockProgress */; };
119120
E81D7EA02805250100A205FC /* Collection+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E81D7E9F2805250100A205FC /* Collection+.swift */; };
120121
E832EAF82B0FBCF4001B570D /* RuntimeInstallationStepDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E832EAF72B0FBCF4001B570D /* RuntimeInstallationStepDetailView.swift */; };
@@ -139,6 +140,7 @@
139140
E8DA461125FAF7FB002E85EF /* NotificationsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8DA461025FAF7FB002E85EF /* NotificationsView.swift */; };
140141
E8E98A9025D8631800EC89A0 /* InstallationStepRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFBC3FF259AC17F00E2A3D8 /* InstallationStepRowView.swift */; };
141142
E8E98A9625D863D700EC89A0 /* InstallationStepDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8E98A9525D863D700EC89A0 /* InstallationStepDetailView.swift */; };
143+
E8EE58C02E1CC2A50003FA9F /* RuntimeArchitecture.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8EE58BF2E1CC2A50003FA9F /* RuntimeArchitecture.swift */; };
142144
E8F44A1E296B4CD7002D6592 /* Path in Frameworks */ = {isa = PBXBuildFile; productRef = E8F44A1D296B4CD7002D6592 /* Path */; };
143145
E8FA00542B5B109800769CE0 /* com.xcodesorg.xcodesapp.Helper in Copy Helper */ = {isa = PBXBuildFile; fileRef = CA9FF8AE2595967A00E47BAF /* com.xcodesorg.xcodesapp.Helper */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
144146
E8FD5727291EE4AC001E004C /* AsyncNetworkService in Frameworks */ = {isa = PBXBuildFile; productRef = E8FD5726291EE4AC001E004C /* AsyncNetworkService */; };
@@ -321,6 +323,7 @@
321323
CAFE4ABB25B7D54B0064FE51 /* UpdatesPreferencePane.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdatesPreferencePane.swift; sourceTree = "<group>"; };
322324
CAFFFED7259CDA5000903F81 /* XcodeListViewRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XcodeListViewRow.swift; sourceTree = "<group>"; };
323325
CAFFFEEE259CEAC400903F81 /* RingProgressViewStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RingProgressViewStyle.swift; sourceTree = "<group>"; };
326+
D93F95C02E0C8C1A00238FB5 /* TagView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagView.swift; sourceTree = "<group>"; };
324327
E81D7E9F2805250100A205FC /* Collection+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+.swift"; sourceTree = "<group>"; };
325328
E832EAF72B0FBCF4001B570D /* RuntimeInstallationStepDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuntimeInstallationStepDetailView.swift; sourceTree = "<group>"; };
326329
E84B7D0C2B296A8900DBDA2B /* NavigationSplitViewWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationSplitViewWrapper.swift; sourceTree = "<group>"; };
@@ -340,6 +343,7 @@
340343
E8D655BF288DD04700A139C2 /* SelectedActionType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectedActionType.swift; sourceTree = "<group>"; };
341344
E8DA461025FAF7FB002E85EF /* NotificationsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsView.swift; sourceTree = "<group>"; };
342345
E8E98A9525D863D700EC89A0 /* InstallationStepDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstallationStepDetailView.swift; sourceTree = "<group>"; };
346+
E8EE58BF2E1CC2A50003FA9F /* RuntimeArchitecture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuntimeArchitecture.swift; sourceTree = "<group>"; };
343347
/* End PBXFileReference section */
344348

345349
/* Begin PBXFrameworksBuildPhase section */
@@ -387,6 +391,7 @@
387391
63EAA4E9259944340046AB8F /* Common */ = {
388392
isa = PBXGroup;
389393
children = (
394+
D93F95C02E0C8C1A00238FB5 /* TagView.swift */,
390395
CAC281CC259F97FA00B8AB0B /* ObservingProgressIndicator.swift */,
391396
63EAA4EA259944450046AB8F /* ProgressButton.swift */,
392397
CA452BAF259FD9770072DFA4 /* ProgressIndicator.swift */,
@@ -657,6 +662,7 @@
657662
E8E98A9425D863B100EC89A0 /* InfoPane */ = {
658663
isa = PBXGroup;
659664
children = (
665+
E8EE58BF2E1CC2A50003FA9F /* RuntimeArchitecture.swift */,
660666
B0403CEF2AD92D7B00137C09 /* ReleaseNotesView.swift */,
661667
B0403CF32AD9381D00137C09 /* SDKsView.swift */,
662668
B0403CF52AD9849E00137C09 /* CompilersView.swift */,
@@ -932,9 +938,11 @@
932938
E84E4F522B323A5F003F3959 /* CornerRadiusModifier.swift in Sources */,
933939
B0403CF22AD934B600137C09 /* CompatibilityView.swift in Sources */,
934940
B0403CFE2ADA712C00137C09 /* InfoPaneControls.swift in Sources */,
941+
D93F95C12E0C8C1A00238FB5 /* TagView.swift in Sources */,
935942
53CBAB2C263DCC9100410495 /* XcodesAlert.swift in Sources */,
936943
332807412CA5EA820036F691 /* SignInSecurityKeyTouchView.swift in Sources */,
937944
CA61A6E0259835580008926E /* Xcode.swift in Sources */,
945+
E8EE58C02E1CC2A50003FA9F /* RuntimeArchitecture.swift in Sources */,
938946
CAE4247F259A666100B8B246 /* MainWindow.swift in Sources */,
939947
CA452BB0259FD9770072DFA4 /* ProgressIndicator.swift in Sources */,
940948
B0403CF02AD92D7B00137C09 /* ReleaseNotesView.swift in Sources */,
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//
2+
// TagView.swift
3+
// Xcodes
4+
//
5+
// Created by Matt Kiazyk on 2025-06-25.//
6+
7+
8+
import SwiftUI
9+
10+
struct TagView: View {
11+
let text: String
12+
13+
var body: some View {
14+
Text(text)
15+
.font(.system(size: 10))
16+
.foregroundColor(.primary)
17+
.padding(.horizontal, 5)
18+
.padding(.vertical, 2)
19+
.background(
20+
Capsule()
21+
.fill(.quaternary)
22+
)
23+
}
24+
}

Xcodes/Frontend/InfoPane/InfoPane.swift

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,7 @@ struct InfoPane: View {
3535
}
3636
.xcodesBackground()
3737

38-
VStack {
39-
Text("Platforms")
40-
.font(.title3)
41-
.frame(maxWidth: .infinity, alignment: .leading)
42-
PlatformsView(xcode: xcode)
43-
}
44-
.xcodesBackground()
38+
PlatformsView(xcode: xcode)
4539
}
4640
.frame(minWidth: 380)
4741

Xcodes/Frontend/InfoPane/PlatformsView.swift

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,59 @@ import XcodesKit
1111

1212
struct PlatformsView: View {
1313
@EnvironmentObject var appState: AppState
14-
14+
@AppStorage("selectedRuntimeArchitecture") private var selectedRuntimeArchitecture: RuntimeArchitecture = .arm64
15+
1516
let xcode: Xcode
1617

1718
var body: some View {
1819

1920
let builds = xcode.sdks?.allBuilds()
2021
let runtimes = builds?.flatMap { sdkBuild in
2122
appState.downloadableRuntimes.filter {
22-
$0.sdkBuildUpdate?.contains(sdkBuild) ?? false
23+
$0.sdkBuildUpdate?.contains(sdkBuild) ?? false &&
24+
($0.architectures?.isEmpty ?? true ||
25+
$0.architectures?.contains(selectedRuntimeArchitecture.rawValue) ?? false)
2326
}
2427
}
25-
26-
ForEach(runtimes ?? [], id: \.simulatorVersion.buildUpdate) { runtime in
27-
runtimeView(runtime: runtime)
28-
.frame(minWidth: 200)
29-
.padding()
30-
.background(.quinary)
31-
.clipShape(RoundedRectangle(cornerRadius: 5, style: .continuous))
28+
29+
let architectures = Set((runtimes ?? []).flatMap { $0.architectures ?? [] })
30+
31+
VStack {
32+
HStack {
33+
Text("Platforms")
34+
.font(.title3)
35+
.frame(maxWidth: .infinity, alignment: .leading)
36+
if !architectures.isEmpty {
37+
Spacer()
38+
Button {
39+
switch selectedRuntimeArchitecture {
40+
case .arm64: selectedRuntimeArchitecture = .x86_64
41+
case .x86_64: selectedRuntimeArchitecture = .arm64
42+
}
43+
} label: {
44+
switch selectedRuntimeArchitecture {
45+
case .arm64:
46+
Label(selectedRuntimeArchitecture.displayValue, systemImage: "m4.button.horizontal")
47+
.labelStyle(.trailingIcon)
48+
case .x86_64:
49+
Label(selectedRuntimeArchitecture.displayValue, systemImage: "cpu.fill")
50+
.labelStyle(.trailingIcon)
51+
}
52+
}
53+
}
54+
}
55+
56+
ForEach(runtimes ?? [], id: \.identifier) { runtime in
57+
runtimeView(runtime: runtime)
58+
.frame(minWidth: 200)
59+
.padding()
60+
.background(.quinary)
61+
.clipShape(RoundedRectangle(cornerRadius: 5, style: .continuous))
62+
}
3263
}
64+
.xcodesBackground()
65+
66+
3367
}
3468

3569
@ViewBuilder
@@ -39,6 +73,9 @@ struct PlatformsView: View {
3973
runtime.icon()
4074
Text("\(runtime.visibleIdentifier)")
4175
.font(.headline)
76+
ForEach(runtime.architectures ?? [], id: \.self) { architecture in
77+
TagView(text: architecture)
78+
}
4279
pathIfAvailable(xcode: xcode, runtime: runtime)
4380

4481
if runtime.installState == .notInstalled {
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//
2+
// RuntimeArchitecture.swift
3+
// Xcodes
4+
//
5+
// Created by Matt Kiazyk on 2025-07-07.
6+
//
7+
8+
enum RuntimeArchitecture: String, CaseIterable, Identifiable {
9+
case arm64
10+
case x86_64
11+
12+
var id: Self { self }
13+
14+
var displayValue: String {
15+
return rawValue
16+
}
17+
}

Xcodes/Frontend/XcodeList/BottomStatusBar.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ struct BottomStatusModifier: ViewModifier {
3434
}
3535
}
3636
}
37-
Text("\(Bundle.main.shortVersion!) (\(Bundle.main.version!))")
37+
Text(verbatim: "\(Bundle.main.shortVersion!) (\(Bundle.main.version!))")
3838
.font(.subheadline)
3939
}
4040
.frame(maxWidth: .infinity, maxHeight: 30, alignment: .leading)

Xcodes/Resources/Licenses.rtf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{\rtf1\ansi\ansicpg1252\cocoartf2818
1+
{\rtf1\ansi\ansicpg1252\cocoartf2822
22
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 .SFNS-Regular;}
33
{\colortbl;\red255\green255\blue255;}
44
{\*\expandedcolortbl;;}

0 commit comments

Comments
 (0)