first async refactor of fetch/index

This commit is contained in:
2024-11-17 02:31:44 +11:00
parent badc6dd39e
commit 8c7f0f23d5
13 changed files with 112 additions and 32 deletions

View File

@ -5,8 +5,9 @@
import Foundation
struct ApkIndexDownloader {
func downloadFile(remote remoteURL: URL, destination destLocalURL: URL) {
public struct ApkIndexDownloader {
@available(*, deprecated, message: "This is stinky, use ApkIndexDownloader.fetch instead")
internal func downloadFile(remote remoteURL: URL, destination destLocalURL: URL) {
let sem = DispatchSemaphore.init(value: 0)
let downloadTask = URLSession.shared.downloadTask(with: remoteURL) { url, response, error in
if let localURL = url {
@ -26,4 +27,49 @@ struct ApkIndexDownloader {
downloadTask.resume()
sem.wait()
}
public static func fetch(repository: ApkIndexRepository) async throws(FetchError) -> URL {
let localDestinationURL = URL(filePath: repository.localName)
let tempLocationURL: URL, response: URLResponse
do {
(tempLocationURL, response) = try await URLSession.shared.download(from: repository.url)
} catch {
throw .downloadFailed(error)
}
guard let httpResponse = response as? HTTPURLResponse,
httpResponse.statusCode == 200 else {
throw .invalidServerResponse((response as? HTTPURLResponse)?.statusCode ?? -1)
}
// Move index repository to destination location
do {
// Replace existing APKINDEX.tar.gz files
if FileManager.default.fileExists(atPath: localDestinationURL.path()) {
try FileManager.default.removeItem(at: localDestinationURL)
}
// Move downloaded file to the new location
try FileManager.default.moveItem(at: tempLocationURL, to: localDestinationURL)
return localDestinationURL
} catch let error {
throw .moveFailed(error)
}
}
}
public extension ApkIndexDownloader {
enum FetchError: Error, LocalizedError {
case invalidServerResponse(_ code: Int)
case downloadFailed(_ err: any Error)
case moveFailed(_ err: any Error)
public var errorDescription: String? {
switch self {
case .invalidServerResponse(let code): "Server responded with HTTP response code \(code)"
case .downloadFailed(let err): "Failed to create session, \(err.localizedDescription)"
case .moveFailed(let err): "Couldn't move index, \(err.localizedDescription)"
}
}
}
}