@@ -26,6 +26,7 @@ enum PreferenceKey: String {
2626 case xcodeListCategory
2727 case allowedMajorVersions
2828 case hideSupportXcodes
29+ case xcodeListArchitectures
2930
3031 func isManaged( ) -> Bool { UserDefaults . standard. objectIsForced ( forKey: self . rawValue) }
3132}
@@ -146,7 +147,7 @@ class AppState: ObservableObject {
146147 // MARK: - Publisher Cancellables
147148
148149 var cancellables = Set < AnyCancellable > ( )
149- private var installationPublishers : [ Version : AnyCancellable ] = [ : ]
150+ private var installationPublishers : [ XcodeID : AnyCancellable ] = [ : ]
150151 internal var runtimePublishers : [ String : Task < ( ) , any Error > ] = [ : ]
151152 private var selectPublisher : AnyCancellable ?
152153 private var uninstallPublisher : AnyCancellable ?
@@ -523,8 +524,8 @@ class AppState: ObservableObject {
523524
524525 // MARK: - Install
525526
526- func checkMinVersionAndInstall( id: Xcode . ID ) {
527- guard let availableXcode = availableXcodes. first ( where: { $0. version == id } ) else { return }
527+ func checkMinVersionAndInstall( id: XcodeID ) {
528+ guard let availableXcode = availableXcodes. first ( where: { $0. xcodeID == id } ) else { return }
528529
529530 // Check to see if users macOS is supported
530531 if let requiredMacOSVersion = availableXcode. requiredMacOSVersion {
@@ -550,8 +551,8 @@ class AppState: ObservableObject {
550551 return !ProcessInfo. processInfo. isOperatingSystemAtLeast ( xcodeMinimumMacOSVersion)
551552 }
552553
553- func install( id: Xcode . ID ) {
554- guard let availableXcode = availableXcodes. first ( where: { $0. version == id } ) else { return }
554+ func install( id: XcodeID ) {
555+ guard let availableXcode = availableXcodes. first ( where: { $0. xcodeID == id } ) else { return }
555556
556557 installationPublishers [ id] = signInIfNeeded ( )
557558 . handleEvents (
@@ -626,7 +627,7 @@ class AppState: ObservableObject {
626627 /// Skips using the username/password to log in to Apple, and simply gets a Auth Cookie used in downloading
627628 /// As of Nov 2022 this was returning a 403 forbidden
628629 func installWithoutLogin( id: Xcode . ID ) {
629- guard let availableXcode = availableXcodes. first ( where: { $0. version == id } ) else { return }
630+ guard let availableXcode = availableXcodes. first ( where: { $0. xcodeID == id } ) else { return }
630631
631632 installationPublishers [ id] = self . install ( . version( availableXcode) , downloader: Downloader ( rawValue: Current . defaults. string ( forKey: " downloader " ) ?? " aria2 " ) ?? . aria2)
632633 . receive ( on: DispatchQueue . main)
@@ -649,7 +650,7 @@ class AppState: ObservableObject {
649650 }
650651
651652 func cancelInstall( id: Xcode . ID ) {
652- guard let availableXcode = availableXcodes. first ( where: { $0. version == id } ) else { return }
653+ guard let availableXcode = availableXcodes. first ( where: { $0. xcodeID == id } ) else { return }
653654
654655 // Cancel the publisher
655656 installationPublishers [ id] = nil
@@ -767,7 +768,7 @@ class AppState: ObservableObject {
767768 config. allowsRunningApplicationSubstitution = false
768769 NSWorkspace . shared. openApplication ( at: path. url, configuration: config)
769770 default :
770- Logger . appState. error ( " \( xcode. id) is not installed " )
771+ Logger . appState. error ( " \( xcode. id. version ) is not installed " )
771772 return
772773 }
773774 }
@@ -863,15 +864,15 @@ class AppState: ObservableObject {
863864 // If build metadata matches exactly, replace the available version with the installed version.
864865 // This should handle Apple versions from /downloads/more which don't have build metadata identifiers.
865866 if let index = adjustedAvailableXcodes. map ( \. version) . firstIndex ( where: { $0. buildMetadataIdentifiers == installedXcode. version. buildMetadataIdentifiers } ) {
866- adjustedAvailableXcodes [ index] . version = installedXcode. version
867+ adjustedAvailableXcodes [ index] . xcodeID = installedXcode. xcodeID
867868 }
868869 // If an installed version is the same as one that's listed online which doesn't have build metadata, replace it with the installed version
869870 // Not all prerelease Apple versions available online include build metadata
870871 else if let index = adjustedAvailableXcodes. firstIndex ( where: { availableXcode in
871872 availableXcode. version. isEquivalent ( to: installedXcode. version) &&
872873 availableXcode. version. buildMetadataIdentifiers. isEmpty
873874 } ) {
874- adjustedAvailableXcodes [ index] . version = installedXcode. version
875+ adjustedAvailableXcodes [ index] . xcodeID = installedXcode. xcodeID
875876 }
876877 }
877878 }
@@ -888,14 +889,21 @@ class AppState: ObservableObject {
888889 // Include this version if there's only one with this build identifier
889890 return availableXcodesWithIdenticalBuildIdentifiers. count == 1 ||
890891 // Or if there's more than one with this build identifier and this is the release version
891- availableXcodesWithIdenticalBuildIdentifiers. count > 1 && availableXcode. version. prereleaseIdentifiers. isEmpty
892- }
892+
893+ availableXcodesWithIdenticalBuildIdentifiers. count > 1 && ( availableXcode. version. prereleaseIdentifiers. isEmpty || availableXcode. architectures? . count ?? 0 != 0 )
894+ }
893895 . map { availableXcode -> Xcode in
894896 let installedXcode = installedXcodes. first ( where: { installedXcode in
895- availableXcode. version. isEquivalent ( to: installedXcode. version)
897+ // if we want to have only specific Xcodes as selected instead of the Architecture Equivalent.
898+ // if availableXcode.architectures == nil {
899+ // return availableXcode.version.isEquivalent(to: installedXcode.version)
900+ // } else {
901+ // return availableXcode.xcodeID == installedXcode.xcodeID
902+ // }
903+ return availableXcode. version. isEquivalent ( to: installedXcode. version)
896904 } )
897905
898- let identicalBuilds : [ Version ]
906+ let identicalBuilds : [ XcodeID ]
899907 let prereleaseAvailableXcodesWithIdenticalBuildIdentifiers = availableXcodes
900908 . filter {
901909 return $0. version. buildMetadataIdentifiers == availableXcode. version. buildMetadataIdentifiers &&
@@ -905,13 +913,13 @@ class AppState: ObservableObject {
905913 }
906914 // If this is the release version, add the identical builds to it
907915 if !prereleaseAvailableXcodesWithIdenticalBuildIdentifiers. isEmpty, availableXcode. version. prereleaseIdentifiers. isEmpty {
908- identicalBuilds = [ availableXcode. version ] + prereleaseAvailableXcodesWithIdenticalBuildIdentifiers. map ( \. version )
916+ identicalBuilds = [ availableXcode. xcodeID ] + prereleaseAvailableXcodesWithIdenticalBuildIdentifiers. map ( \. xcodeID )
909917 } else {
910918 identicalBuilds = [ ]
911919 }
912920
913921 // If the existing install state is "installing", keep it
914- let existingXcodeInstallState = allXcodes. first { $0. version == availableXcode. version && $0. installState. installing } ? . installState
922+ let existingXcodeInstallState = allXcodes. first { $0. id == availableXcode. xcodeID && $0. installState. installing } ? . installState
915923 // Otherwise, determine it from whether there's an installed Xcode
916924 let defaultXcodeInstallState : XcodeInstallState = installedXcode. map { . installed( $0. path) } ?? . notInstalled
917925
@@ -926,7 +934,8 @@ class AppState: ObservableObject {
926934 releaseDate: availableXcode. releaseDate,
927935 sdks: availableXcode. sdks,
928936 compilers: availableXcode. compilers,
929- downloadFileSize: availableXcode. fileSize
937+ downloadFileSize: availableXcode. fileSize,
938+ architectures: availableXcode. architectures
930939 )
931940 }
932941
0 commit comments