Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions Xcodes.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,9 @@
E689540325BE8C64000EBCEA /* DockProgress in Frameworks */ = {isa = PBXBuildFile; productRef = E689540225BE8C64000EBCEA /* DockProgress */; };
E81D7EA02805250100A205FC /* Collection+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E81D7E9F2805250100A205FC /* Collection+.swift */; };
E832EAF82B0FBCF4001B570D /* RuntimeInstallationStepDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E832EAF72B0FBCF4001B570D /* RuntimeInstallationStepDetailView.swift */; };
E84CF8C12B0FEB8300ECA259 /* RuntimesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E84CF8C02B0FEB8300ECA259 /* RuntimesView.swift */; };
E872EE4E2808D4F100D3DD8B /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E872EE502808D4F100D3DD8B /* Localizable.strings */; };
E84B7D0D2B296A8900DBDA2B /* NavigationSplitViewWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = E84B7D0C2B296A8900DBDA2B /* NavigationSplitViewWrapper.swift */; };
E84E4F522B323A5F003F3959 /* CornerRadiusModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = E84E4F512B323A5F003F3959 /* CornerRadiusModifier.swift */; };
E86671272B309D2F0048559A /* PlatformsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E86671262B309D2F0048559A /* PlatformsView.swift */; };
E87AB3C52939B65E00D72F43 /* Hardware.swift in Sources */ = {isa = PBXBuildFile; fileRef = E87AB3C42939B65E00D72F43 /* Hardware.swift */; };
E87DD6EB25D053FA00D86808 /* Progress+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E87DD6EA25D053FA00D86808 /* Progress+.swift */; };
E89342FA25EDCC17007CF557 /* NotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E89342F925EDCC17007CF557 /* NotificationManager.swift */; };
Expand Down Expand Up @@ -310,9 +311,10 @@
CAFFFEEE259CEAC400903F81 /* RingProgressViewStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RingProgressViewStyle.swift; sourceTree = "<group>"; };
E81D7E9F2805250100A205FC /* Collection+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+.swift"; sourceTree = "<group>"; };
E832EAF72B0FBCF4001B570D /* RuntimeInstallationStepDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuntimeInstallationStepDetailView.swift; sourceTree = "<group>"; };
E84CF8C02B0FEB8300ECA259 /* RuntimesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuntimesView.swift; sourceTree = "<group>"; };
E84B7D0C2B296A8900DBDA2B /* NavigationSplitViewWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationSplitViewWrapper.swift; sourceTree = "<group>"; };
E84E4F512B323A5F003F3959 /* CornerRadiusModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CornerRadiusModifier.swift; sourceTree = "<group>"; };
E856BB73291EDD3D00DC438B /* XcodesKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = XcodesKit; path = Xcodes/XcodesKit; sourceTree = "<group>"; };
E872EE4F2808D4F100D3DD8B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
E86671262B309D2F0048559A /* PlatformsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlatformsView.swift; sourceTree = "<group>"; };
E87AB3C42939B65E00D72F43 /* Hardware.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Hardware.swift; sourceTree = "<group>"; };
E87DD6EA25D053FA00D86808 /* Progress+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Progress+.swift"; sourceTree = "<group>"; };
E89342F925EDCC17007CF557 /* NotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationManager.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -373,6 +375,7 @@
CA452BAF259FD9770072DFA4 /* ProgressIndicator.swift */,
536CFDD3263C9A8000026CE0 /* XcodesSheet.swift */,
53CBAB2B263DCC9100410495 /* XcodesAlert.swift */,
E84B7D0C2B296A8900DBDA2B /* NavigationSplitViewWrapper.swift */,
);
path = Common;
sourceTree = "<group>";
Expand Down Expand Up @@ -646,7 +649,8 @@
B0C6AD0A2AD9178E00E64698 /* IdenticalBuildView.swift */,
B0C6AD0C2AD91D7900E64698 /* IconView.swift */,
E832EAF72B0FBCF4001B570D /* RuntimeInstallationStepDetailView.swift */,
E84CF8C02B0FEB8300ECA259 /* RuntimesView.swift */,
E86671262B309D2F0048559A /* PlatformsView.swift */,
E84E4F512B323A5F003F3959 /* CornerRadiusModifier.swift */,
);
path = InfoPane;
sourceTree = "<group>";
Expand Down Expand Up @@ -868,7 +872,6 @@
CA9FF8CF25959A9700E47BAF /* HelperXPCShared.swift in Sources */,
CA735109257BF96D00EA9CF8 /* AttributedText.swift in Sources */,
CAFBDC4E2599B33D003DCC5A /* MainToolbar.swift in Sources */,
E84CF8C12B0FEB8300ECA259 /* RuntimesView.swift in Sources */,
CA11E7BA2598476C00D2EE1C /* XcodeCommands.swift in Sources */,
CAA8589B25A2B83000ACF8C0 /* Aria2CError.swift in Sources */,
536CFDD2263C94DE00026CE0 /* SignedInView.swift in Sources */,
Expand Down Expand Up @@ -897,6 +900,7 @@
B0403CFC2AD9A6BF00137C09 /* InstalledStateButtons.swift in Sources */,
36741BFF291E50F500A85AAE /* FileError.swift in Sources */,
CA9FF8872595607900E47BAF /* InstalledXcode.swift in Sources */,
E84E4F522B323A5F003F3959 /* CornerRadiusModifier.swift in Sources */,
B0403CF22AD934B600137C09 /* CompatibilityView.swift in Sources */,
B0403CFE2ADA712C00137C09 /* InfoPaneControls.swift in Sources */,
53CBAB2C263DCC9100410495 /* XcodesAlert.swift in Sources */,
Expand All @@ -910,6 +914,7 @@
CABFA9C12592EEEA00380FEE /* Version+.swift in Sources */,
E8D655C0288DD04700A139C2 /* SelectedActionType.swift in Sources */,
36741BFD291E4FDB00A85AAE /* DownloadPreferencePane.swift in Sources */,
E86671272B309D2F0048559A /* PlatformsView.swift in Sources */,
CA9FF8522595080100E47BAF /* AcknowledgementsView.swift in Sources */,
CABFA9CE2592EEEA00380FEE /* Version+Xcode.swift in Sources */,
CAFBDB912598FE80003DCC5A /* SelectedXcode.swift in Sources */,
Expand All @@ -921,6 +926,7 @@
E8B20CBF2A2EDEC20057D816 /* SDKs+Xcode.swift in Sources */,
CA9FF877259528CC00E47BAF /* Version+XcodeReleases.swift in Sources */,
CABFAA2D2592FBFC00380FEE /* Configure.swift in Sources */,
E84B7D0D2B296A8900DBDA2B /* NavigationSplitViewWrapper.swift in Sources */,
CA73510D257BFCEF00EA9CF8 /* NSAttributedString+.swift in Sources */,
CAFBDB952598FE96003DCC5A /* FocusedValues.swift in Sources */,
B0403CF42AD9381D00137C09 /* SDKsView.swift in Sources */,
Expand Down Expand Up @@ -1040,7 +1046,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MACOSX_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
Expand Down Expand Up @@ -1227,7 +1233,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MACOSX_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
Expand Down Expand Up @@ -1285,7 +1291,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MACOSX_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = macosx;
Expand Down
1 change: 1 addition & 0 deletions Xcodes/Backend/AppState+Runtimes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ extension AppState {
Task {
do {
let runtimes = try await self.runtimeService.localInstalledRuntimes()

DispatchQueue.main.async {
self.installedRuntimes = runtimes
}
Expand Down
13 changes: 8 additions & 5 deletions Xcodes/Backend/AppState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ class AppState: ObservableObject {
checkIfHelperIsInstalled()
setupAutoInstallTimer()
setupDefaults()
updateInstalledRuntimes()
}

func setupDefaults() {
Expand Down Expand Up @@ -410,10 +409,7 @@ class AppState: ObservableObject {

// Check to see if users MacOS is supported
if let requiredMacOSVersion = availableXcode.requiredMacOSVersion {
let split = requiredMacOSVersion.components(separatedBy: ".").compactMap { Int($0) }
let xcodeMinimumMacOSVersion = OperatingSystemVersion(majorVersion: split[safe: 0] ?? 0, minorVersion: split[safe: 1] ?? 0, patchVersion: split[safe: 2] ?? 0)

if !ProcessInfo.processInfo.isOperatingSystemAtLeast(xcodeMinimumMacOSVersion) {
if hasMinSupportedOS(requiredMacOSVersion: requiredMacOSVersion) {
// prompt
self.presentedAlert = .checkMinSupportedVersion(xcode: availableXcode, macOS: ProcessInfo.processInfo.operatingSystemVersion.versionString())
return
Expand All @@ -428,6 +424,13 @@ class AppState: ObservableObject {
}
}

func hasMinSupportedOS(requiredMacOSVersion: String) -> Bool {
let split = requiredMacOSVersion.components(separatedBy: ".").compactMap { Int($0) }
let xcodeMinimumMacOSVersion = OperatingSystemVersion(majorVersion: split[safe: 0] ?? 0, minorVersion: split[safe: 1] ?? 0, patchVersion: split[safe: 2] ?? 0)

return !ProcessInfo.processInfo.isOperatingSystemAtLeast(xcodeMinimumMacOSVersion)
}

func install(id: Xcode.ID) {
guard let availableXcode = availableXcodes.first(where: { $0.version == id }) else { return }

Expand Down
23 changes: 23 additions & 0 deletions Xcodes/Backend/SDKs+Xcode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

import Foundation
import struct XCModel.SDKs
import XcodesKit
import SwiftUI

extension SDKs {
/// Loops through all SDK's and returns an array of buildNumbers (to be used to correlate runtimes)
Expand All @@ -33,3 +35,24 @@ extension SDKs {
return buildNumbers
}
}

extension DownloadableRuntime {
func icon() -> Image {
switch self.platform {
case .iOS:
return Image(systemName: "iphone")
case .macOS:
return Image(systemName: "macwindow")
case .watchOS:
return Image(systemName: "applewatch")
case .tvOS:
return Image(systemName: "appletv")
case .visionOS:
if #available(macOS 14, *) {
return Image(systemName: "visionpro")
} else {
return Image(systemName: "eyeglasses")
}
}
}
}
11 changes: 6 additions & 5 deletions Xcodes/Backend/XcodeCommands.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,10 @@ struct CancelInstallButton: View {

var body: some View {
Button(action: cancelInstall) {
Text("Cancel")
.help(localizeString("StopInstallation"))
Image(systemName: "xmark.circle.fill")
}
.help(localizeString("StopInstallation"))
.buttonStyle(.plain)
}

private func cancelInstall() {
Expand All @@ -78,9 +79,9 @@ struct CancelRuntimeInstallButton: View {

var body: some View {
Button(action: cancelInstall) {
Text("Cancel")
.help(localizeString("StopInstallation"))
}
Image(systemName: "xmark.circle.fill")
}.help(localizeString("StopInstallation"))
.buttonStyle(.plain)
}

private func cancelInstall() {
Expand Down
46 changes: 46 additions & 0 deletions Xcodes/Frontend/Common/NavigationSplitViewWrapper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// NavigationSplitViewWrapper.swift
// Xcodes
//
// Created by Matt Kiazyk on 2023-12-12.
//

import SwiftUI

struct NavigationSplitViewWrapper<Sidebar, Detail>: View where Sidebar: View, Detail: View {
private var sidebar: Sidebar
private var detail: Detail

init(
@ViewBuilder sidebar: () -> Sidebar,
@ViewBuilder detail: () -> Detail
) {
self.sidebar = sidebar()
self.detail = detail()
}

var body: some View {
if #available(iOS 16, macOS 13, tvOS 16, watchOS 9, visionOS 1, *) {
// Use the latest API available
NavigationSplitView {

if #available(macOS 14, *) {
sidebar
.toolbar(removing: .sidebarToggle)
} else {
sidebar
}
} detail: {
detail
}
} else {
// Alternative code for earlier versions of OS.
NavigationView {
// The first column is the sidebar.
sidebar
detail
}
.navigationViewStyle(.columns)
}
}
}
22 changes: 17 additions & 5 deletions Xcodes/Frontend/InfoPane/CompatibilityView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,27 @@
import SwiftUI

struct CompatibilityView: View {
@EnvironmentObject var appState: AppState

let requiredMacOSVersion: String?

var body: some View {
if let requiredMacOSVersion = requiredMacOSVersion {
VStack(alignment: .leading) {
Text("Compatibility")
.font(.headline)
Text(String(format: localizeString("MacOSRequirement"), requiredMacOSVersion))
.font(.subheadline)
HStack(alignment: .top){
VStack(alignment: .leading) {
Text("Compatibility")
.font(.headline)
Text(String(format: localizeString("MacOSRequirement"), requiredMacOSVersion))
.font(.subheadline)
.foregroundColor(appState.hasMinSupportedOS(requiredMacOSVersion: requiredMacOSVersion) ? .red : .primary)
}
Spacer()
if appState.hasMinSupportedOS(requiredMacOSVersion: requiredMacOSVersion) {
Image(systemName: "exclamationmark.triangle.fill")
.font(.largeTitle)
}
}
.xcodesBackground()
} else {
EmptyView()
}
Expand All @@ -28,4 +39,5 @@ struct CompatibilityView: View {
#Preview {
CompatibilityView(requiredMacOSVersion: "10.15.4")
.padding()
.environmentObject(AppState())
}
35 changes: 35 additions & 0 deletions Xcodes/Frontend/InfoPane/CornerRadiusModifier.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// CornerRadiusModifier.swift
// Xcodes
//
// Created by Matt Kiazyk on 2023-12-19.
//

import Foundation
import SwiftUI

struct CornerRadiusModifier: ViewModifier {
func body(content: Content) -> some View {
content
.frame(maxWidth: .infinity, alignment: .leading)
.padding()
.background(.background)
.clipShape(RoundedRectangle(cornerRadius: 5, style: .continuous))
}
}

extension View {
func xcodesBackground() -> some View {
self.modifier(
CornerRadiusModifier()
)
}
}

struct Previews_CornerRadius_Previews: PreviewProvider {
static var previews: some View {
HStack {
Text("XCODES RULES!")
}.xcodesBackground()
}
}
1 change: 1 addition & 0 deletions Xcodes/Frontend/InfoPane/IdenticalBuildView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ struct IdenticalBuildsView: View {
.font(.subheadline)
}
}
.xcodesBackground()
.accessibilityElement()
.accessibility(label: Text("IdenticalBuilds"))
.accessibility(value: Text(accessibilityDescription))
Expand Down
Loading