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
27 changes: 27 additions & 0 deletions Xcodes.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@
E832EAF82B0FBCF4001B570D /* RuntimeInstallationStepDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E832EAF72B0FBCF4001B570D /* RuntimeInstallationStepDetailView.swift */; };
E84B7D0D2B296A8900DBDA2B /* NavigationSplitViewWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = E84B7D0C2B296A8900DBDA2B /* NavigationSplitViewWrapper.swift */; };
E84E4F522B323A5F003F3959 /* CornerRadiusModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = E84E4F512B323A5F003F3959 /* CornerRadiusModifier.swift */; };
E84E4F542B333864003F3959 /* PlatformsListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E84E4F532B333864003F3959 /* PlatformsListView.swift */; };
E84E4F572B335094003F3959 /* OrderedCollections in Frameworks */ = {isa = PBXBuildFile; productRef = E84E4F562B335094003F3959 /* OrderedCollections */; };
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 */; };
Expand Down Expand Up @@ -313,6 +315,7 @@
E832EAF72B0FBCF4001B570D /* RuntimeInstallationStepDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuntimeInstallationStepDetailView.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>"; };
E84E4F532B333864003F3959 /* PlatformsListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlatformsListView.swift; sourceTree = "<group>"; };
E856BB73291EDD3D00DC438B /* XcodesKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = XcodesKit; path = Xcodes/XcodesKit; 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>"; };
Expand Down Expand Up @@ -352,6 +355,7 @@
E8FD5727291EE4AC001E004C /* AsyncNetworkService in Frameworks */,
CAA1CB2D255A5262003FD669 /* AppleAPI in Frameworks */,
CABFA9EE2592F0CC00380FEE /* SwiftSoup in Frameworks */,
E84E4F572B335094003F3959 /* OrderedCollections in Frameworks */,
E8F44A1E296B4CD7002D6592 /* Path in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -628,6 +632,7 @@
E8977EA225C11E1500835F80 /* PreferencesView.swift */,
E8DA461025FAF7FB002E85EF /* NotificationsView.swift */,
E8CBDB8A27AE02FF00B22292 /* ExperiementsPreferencePane.swift */,
E84E4F532B333864003F3959 /* PlatformsListView.swift */,
);
path = Preferences;
sourceTree = "<group>";
Expand Down Expand Up @@ -705,6 +710,7 @@
E8FD5726291EE4AC001E004C /* AsyncNetworkService */,
E8C0EB19291EF43E0081528A /* XcodesKit */,
E8F44A1D296B4CD7002D6592 /* Path */,
E84E4F562B335094003F3959 /* OrderedCollections */,
);
productName = XcodesMac;
productReference = CAD2E79E2449574E00113D76 /* Xcodes.app */;
Expand Down Expand Up @@ -791,6 +797,7 @@
E689540125BE8C64000EBCEA /* XCRemoteSwiftPackageReference "DockProgress" */,
E8FD5725291EE4AC001E004C /* XCRemoteSwiftPackageReference "AsyncHTTPNetworkService" */,
E8F44A1C296B4CD7002D6592 /* XCRemoteSwiftPackageReference "Path" */,
E84E4F552B335094003F3959 /* XCRemoteSwiftPackageReference "swift-collections" */,
);
productRefGroup = CAD2E79F2449574E00113D76 /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -914,6 +921,7 @@
CABFA9C12592EEEA00380FEE /* Version+.swift in Sources */,
E8D655C0288DD04700A139C2 /* SelectedActionType.swift in Sources */,
36741BFD291E4FDB00A85AAE /* DownloadPreferencePane.swift in Sources */,
E84E4F542B333864003F3959 /* PlatformsListView.swift in Sources */,
E86671272B309D2F0048559A /* PlatformsView.swift in Sources */,
CA9FF8522595080100E47BAF /* AcknowledgementsView.swift in Sources */,
CABFA9CE2592EEEA00380FEE /* Version+Xcode.swift in Sources */,
Expand Down Expand Up @@ -1075,6 +1083,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.10.0;
PRODUCT_BUNDLE_IDENTIFIER = com.xcodesorg.xcodesapp;
PRODUCT_NAME = Xcodes;
Expand All @@ -1098,6 +1107,7 @@
"@executable_path/../Frameworks",
"@loader_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.0;
PRODUCT_BUNDLE_IDENTIFIER = com.robotsandpencils.XcodesAppTests;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down Expand Up @@ -1318,6 +1328,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.10.0;
PRODUCT_BUNDLE_IDENTIFIER = com.xcodesorg.xcodesapp;
PRODUCT_NAME = Xcodes;
Expand All @@ -1342,6 +1353,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.10.0;
PRODUCT_BUNDLE_IDENTIFIER = com.xcodesorg.xcodesapp;
PRODUCT_NAME = Xcodes;
Expand All @@ -1363,6 +1375,7 @@
"@executable_path/../Frameworks",
"@loader_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.0;
PRODUCT_BUNDLE_IDENTIFIER = com.robotsandpencils.XcodesAppTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
Expand All @@ -1384,6 +1397,7 @@
"@executable_path/../Frameworks",
"@loader_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.0;
PRODUCT_BUNDLE_IDENTIFIER = com.robotsandpencils.XcodesAppTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
Expand Down Expand Up @@ -1501,6 +1515,14 @@
minimumVersion = 3.2.0;
};
};
E84E4F552B335094003F3959 /* XCRemoteSwiftPackageReference "swift-collections" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/apple/swift-collections.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 1.0.5;
};
};
E8F44A1C296B4CD7002D6592 /* XCRemoteSwiftPackageReference "Path" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/mxcl/Path.swift";
Expand Down Expand Up @@ -1572,6 +1594,11 @@
package = E689540125BE8C64000EBCEA /* XCRemoteSwiftPackageReference "DockProgress" */;
productName = DockProgress;
};
E84E4F562B335094003F3959 /* OrderedCollections */ = {
isa = XCSwiftPackageProductDependency;
package = E84E4F552B335094003F3959 /* XCRemoteSwiftPackageReference "swift-collections" */;
productName = OrderedCollections;
};
E8C0EB19291EF43E0081528A /* XcodesKit */ = {
isa = XCSwiftPackageProductDependency;
productName = XcodesKit;
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions Xcodes/Backend/AppState+Install.swift
Original file line number Diff line number Diff line change
Expand Up @@ -500,12 +500,13 @@ extension AppState {
}
}

func setInstallationStep(of runtime: DownloadableRuntime, to step: RuntimeInstallationStep) {
func setInstallationStep(of runtime: DownloadableRuntime, to step: RuntimeInstallationStep, postNotification: Bool = true) {
DispatchQueue.main.async {
guard let index = self.downloadableRuntimes.firstIndex(where: { $0.identifier == runtime.identifier }) else { return }
self.downloadableRuntimes[index].installState = .installing(step)

Current.notificationManager.scheduleNotification(title: runtime.name, body: step.description, category: .normal)
if postNotification {
Current.notificationManager.scheduleNotification(title: runtime.name, body: step.description, category: .normal)
}
}
}
}
Expand Down
37 changes: 33 additions & 4 deletions Xcodes/Backend/AppState+Runtimes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ extension AppState {
func updateInstalledRuntimes() {
Task {
do {
Logger.appState.info("Loading Installed runtimes")
let runtimes = try await self.runtimeService.localInstalledRuntimes()

DispatchQueue.main.async {
Expand All @@ -51,7 +52,7 @@ extension AppState {
do {
let downloadedURL = try await downloadRunTimeFull(runtime: runtime)
if !Task.isCancelled {
Logger.appState.debug("Installing rungtime: \(runtime.name)")
Logger.appState.debug("Installing runtime: \(runtime.name)")
DispatchQueue.main.async {
self.setInstallationStep(of: runtime, to: .installing)
}
Expand Down Expand Up @@ -110,11 +111,10 @@ extension AppState {
let aria2Path = Path(url: Bundle.main.url(forAuxiliaryExecutable: "aria2c")!)!
for try await progress in downloadRuntimeWithAria2(runtime, to: expectedRuntimePath, aria2Path: aria2Path) {
DispatchQueue.main.async {
Logger.appState.debug("Downloading: \(progress.fractionCompleted)")
self.setInstallationStep(of: runtime, to: .downloading(progress: progress))
self.setInstallationStep(of: runtime, to: .downloading(progress: progress), postNotification: false)
}
}
Logger.appState.debug("Done downloading")
Logger.appState.debug("Done downloading runtime")

case .urlSession:
throw "Downloading runtimes with URLSession is not supported. Please use aria2"
Expand Down Expand Up @@ -210,6 +210,35 @@ extension AppState {

updateInstalledRuntimes()
}

func runtimeInstallPath(xcode: Xcode, runtime: DownloadableRuntime) -> Path? {
if let coreSimulatorInfo = coreSimulatorInfo(runtime: runtime) {
let urlString = coreSimulatorInfo.path["relative"]!
// app was not allowed to open up file:// url's so remove
let fileRemovedString = urlString.replacingOccurrences(of: "file://", with: "")
let url = URL(fileURLWithPath: fileRemovedString)

return Path(url: url)!
}
return nil
}

func coreSimulatorInfo(runtime: DownloadableRuntime) -> CoreSimulatorImage? {
return installedRuntimes.filter({ $0.runtimeInfo.build == runtime.simulatorVersion.buildUpdate }).first
}

func deleteRuntime(runtime: DownloadableRuntime) async throws {
if let info = coreSimulatorInfo(runtime: runtime) {
try await runtimeService.deleteRuntime(identifier: info.uuid)

// give it some time to actually finish deleting before updating
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in
self?.updateInstalledRuntimes()
}
} else {
throw "No simulator found with \(runtime.identifier)"
}
}
}

extension AnyPublisher {
Expand Down
15 changes: 2 additions & 13 deletions Xcodes/Backend/AppState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class AppState: ObservableObject {
@Published var isProcessingAuthRequest = false
@Published var xcodeBeingConfirmedForUninstallation: Xcode?
@Published var presentedAlert: XcodesAlert?
@Published var presentedPreferenceAlert: XcodesPreferencesAlert?
@Published var helperInstallState: HelperInstallState = .notInstalled
/// Whether the user is being prepared for the helper installation alert with an explanation.
/// This closure will be performed after the user chooses whether or not to proceed.
Expand Down Expand Up @@ -824,19 +825,7 @@ class AppState: ObservableObject {

self.allXcodes = newAllXcodes.sorted { $0.version > $1.version }
}

// MARK: Runtimes
func runtimeInstallPath(xcode: Xcode, runtime: DownloadableRuntime) -> Path? {
if let coreSimulatorInfo = installedRuntimes.filter({ $0.runtimeInfo.build == runtime.simulatorVersion.buildUpdate }).first {
let urlString = coreSimulatorInfo.path["relative"]!
// app was not allowed to open up file:// url's so remove
let fileRemovedString = urlString.replacingOccurrences(of: "file://", with: "")
let url = URL(fileURLWithPath: fileRemovedString)

return Path(url: url)!
}
return nil
}


// MARK: - Private

Expand Down
14 changes: 14 additions & 0 deletions Xcodes/Frontend/Common/XcodesAlert.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,17 @@ enum XcodesAlert: Identifiable {
}
}
}

// Splitting out alerts that are shown on the preference screen as by default we are showing on the MainWindow()
// and users awkwardly switch screens, sometimes losing the preference screen
enum XcodesPreferencesAlert: Identifiable {
case deletePlatform(runtime: DownloadableRuntime)
case generic(title: String, message: String)

var id: Int {
switch self {
case .deletePlatform: return 1
case .generic: return 2
}
}
}
3 changes: 2 additions & 1 deletion Xcodes/Frontend/InfoPane/InfoPane.swift
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ var downloadableRuntimes: [DownloadableRuntime] = {
}()

var installedRuntimes: [CoreSimulatorImage] = {
[CoreSimulatorImage(uuid: "85B22F5B-048B-4331-B6E2-F4196D8B7475", path: ["relative" : "file:///Library/Developer/CoreSimulator/Images/85B22F5B-048B-4331-B6E2-F4196D8B7475.dmg"], runtimeInfo: CoreSimulatorRuntimeInfo(build: "19E240"))] // same as iOS in _SDK's
[CoreSimulatorImage(uuid: "85B22F5B-048B-4331-B6E2-F4196D8B7475", path: ["relative" : "file:///Library/Developer/CoreSimulator/Images/85B22F5B-048B-4331-B6E2-F4196D8B7475.dmg"], runtimeInfo: CoreSimulatorRuntimeInfo(build: "19E240")),
CoreSimulatorImage(uuid: "85B22F5B-048B-4331-B6E2-F4196D8B7473", path: ["relative" : "file:///Library/Developer/CoreSimulator/Images/85B22F5B-048B-4331-B6E2-F4196D8B7475.dmg"], runtimeInfo: CoreSimulatorRuntimeInfo(build: "21N5233f"))]
}()


Expand Down
1 change: 1 addition & 0 deletions Xcodes/Frontend/InfoPane/PlatformsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ struct PlatformsView: View {
HStack(alignment: .top, spacing: 5){
RuntimeInstallationStepDetailView(installationStep: installationStep)
.fixedSize(horizontal: false, vertical: true)
Spacer()
CancelRuntimeInstallButton(runtime: runtime)
}

Expand Down
26 changes: 0 additions & 26 deletions Xcodes/Frontend/MainWindow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,32 +69,6 @@ struct MainWindow: View {
}
}
}

// HSplitView {
// XcodeListView(selectedXcodeID: $selectedXcodeID, searchText: searchText, category: category, isInstalledOnly: isInstalledOnly)
// .frame(minWidth: 300)
// .layoutPriority(1)
// .alert(item: $appState.xcodeBeingConfirmedForUninstallation) { xcode in
// Alert(title: Text(String(format: localizeString("Alert.Uninstall.Title"), xcode.description)),
// message: Text("Alert.Uninstall.Message"),
// primaryButton: .destructive(Text("Uninstall"), action: { self.appState.uninstall(xcode: xcode) }),
// secondaryButton: .cancel(Text("Cancel")))
// }
// .searchable(text: $searchText)
//
// if isShowingInfoPane {
// Group {
// if let xcode = xcode {
// InfoPane(xcode: xcode)
// } else {
// UnselectedView()
// }
// }
// .padding()
// .frame(minWidth: 300, maxWidth: .infinity)
// }
// }

.bottomStatusBar()
.padding([.top], 0)
.navigationSubtitle(subtitleText)
Expand Down
Loading