Skip to content

Commit

Permalink
Merge pull request #585 from XcodesOrg/matt/iOS18Runtimes
Browse files Browse the repository at this point in the history
Fix runtime downloading
  • Loading branch information
MattKiazyk authored Jun 28, 2024
2 parents 8a6f5a7 + a587d53 commit b361651
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 14 deletions.
36 changes: 30 additions & 6 deletions Xcodes/Backend/AppState+Runtimes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ extension AppState {
self.setInstallationStep(of: runtime, to: .installing)
}
switch runtime.contentType {
case .cryptexDiskImage:
// not supported yet (do we need to for old packages?)
throw "Installing via cryptexDiskImage not support - please install manually from \(downloadedURL.description)"
case .package:
// not supported yet (do we need to for old packages?)
throw "Installing via package not support - please install manually from \(downloadedURL.description)"
Expand All @@ -80,19 +83,31 @@ extension AppState {
Logger.appState.error("Error downloading runtime: \(error.localizedDescription)")
DispatchQueue.main.async {
self.error = error
self.presentedAlert = .generic(title: localizeString("Alert.Install.Error.Title"), message: error.legibleLocalizedDescription)
if let error = error as? String {
self.presentedAlert = .generic(title: localizeString("Alert.Install.Error.Title"), message: error)
} else {
self.presentedAlert = .generic(title: localizeString("Alert.Install.Error.Title"), message: error.legibleLocalizedDescription)
}
}
}
}
}

func downloadRunTimeFull(runtime: DownloadableRuntime) async throws -> URL {
guard let source = runtime.source else {
throw "Invalid runtime source"
}

guard let downloadPath = runtime.downloadPath else {
throw "Invalid runtime downloadPath"
}

// sets a proper cookie for runtimes
try await validateADCSession(path: runtime.downloadPath)
try await validateADCSession(path: downloadPath)

let downloader = Downloader(rawValue: UserDefaults.standard.string(forKey: "downloader") ?? "aria2") ?? .aria2

let url = URL(string: runtime.source)!
let url = URL(string: source)!
let expectedRuntimePath = Path.xcodesApplicationSupport/"\(url.lastPathComponent)"
// aria2 downloads directly to the destination (instead of into /tmp first) so we need to make sure that the download isn't incomplete
let aria2DownloadMetadataPath = expectedRuntimePath.parent/(expectedRuntimePath.basename() + ".aria2")
Expand Down Expand Up @@ -123,9 +138,15 @@ extension AppState {
}

public func downloadRuntimeWithAria2(_ runtime: DownloadableRuntime, to destination: Path, aria2Path: Path) -> AsyncThrowingStream<Progress, Error> {
let cookies = AppleAPI.Current.network.session.configuration.httpCookieStorage?.cookies(for: runtime.url) ?? []
guard let url = runtime.url else {
return AsyncThrowingStream<Progress, Error> { continuation in
continuation.finish(throwing: "Invalid or non existant runtime url")
}
}

let cookies = AppleAPI.Current.network.session.configuration.httpCookieStorage?.cookies(for: url) ?? []

return Current.shell.downloadWithAria2Async(aria2Path, runtime.url, destination, cookies)
return Current.shell.downloadWithAria2Async(aria2Path, url, destination, cookies)
}


Expand All @@ -140,7 +161,10 @@ extension AppState {
runtimePublishers[runtime.identifier] = nil

// If the download is cancelled by the user, clean up the download files that aria2 creates.
let url = URL(string: runtime.source)!
guard let source = runtime.source else {
return
}
let url = URL(string: source)!
let expectedRuntimePath = Path.xcodesApplicationSupport/"\(url.lastPathComponent)"
let aria2DownloadMetadataPath = expectedRuntimePath.parent/(expectedRuntimePath.basename() + ".aria2")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public struct DownloadableRuntimesResponse: Codable {
public struct DownloadableRuntime: Codable, Identifiable, Hashable {
public let category: Category
public let simulatorVersion: SimulatorVersion
public let source: String
public let source: String?
public let dictionaryVersion: Int
public let contentType: ContentType
public let platform: Platform
Expand All @@ -21,11 +21,14 @@ public struct DownloadableRuntime: Codable, Identifiable, Hashable {
public let hostRequirements: HostRequirements?
public let name: String
public let authentication: Authentication?
public var url: URL {
return URL(string: source)!
public var url: URL? {
if let source {
return URL(string: source)!
}
return nil
}
public var downloadPath: String {
url.path
public var downloadPath: String? {
url?.path
}

// dynamically updated - not decoded
Expand Down Expand Up @@ -117,6 +120,7 @@ extension DownloadableRuntime {
public enum ContentType: String, Codable {
case diskImage = "diskImage"
case package = "package"
case cryptexDiskImage = "cryptexDiskImage"
}

public enum Platform: String, Codable {
Expand Down
11 changes: 8 additions & 3 deletions Xcodes/XcodesKit/Sources/XcodesKit/Services/RuntimeService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,14 @@ public struct RuntimeService {

// Apple gives a plist for download
let (data, _) = try await networkService.requestData(urlRequest, validators: [])
let decodedResponse = try PropertyListDecoder().decode(DownloadableRuntimesResponse.self, from: data)

return decodedResponse
do {
let decodedResponse = try PropertyListDecoder().decode(DownloadableRuntimesResponse.self, from: data)
return decodedResponse
} catch {
print("error: \(error)")
throw error
}

}

public func installedRuntimes() async throws -> [InstalledRuntime] {
Expand Down

0 comments on commit b361651

Please sign in to comment.