swift - macOS 命令行代码在 Swift 中获取数据的现代方式,并带有进度通知

标签 swift macos https command-line progress

老程序员,但苹果生态系统的新手。我想使用最现代的 API 和 Swift 技术通过 https 获取一些数据并获取进度报告。

我能找到的大多数教程和示例都使用我认为现在已经过时的技术,例如 RunLoop 或信号量。或者它们用于已经有委托(delegate)的 GUI 代码。

我能够走到这一步,使用 async/await 从用 @main 注释的结构内部获取数据,该结构具有一个静态异步函数。

它使用 URLSession.shared.data(for: 所以我不必提供委托(delegate)。

我不确定是否有办法为此添加进度报告。或者更有可能我需要一名代表。在这种情况下,我一直无法找到如何为这个最小的用例创建一个简单的委托(delegate)。或者也许还有我还没有发现的不同方式?

    import Foundation
    
    func fetchData() async throws -> Data {
        // this is a 1 megabyte text file, big enough for updates
        let url = URL(string: "https://gist.github.com/khaykov/a6105154becce4c0530da38e723c2330/raw/41ab415ac41c93a198f7da5b47d604956157c5c3/gistfile1.txt")!
    
        var request = URLRequest(url: url)
    
        let (data, _) = try await URLSession.shared.data(for: request)
        return data
    }
    
    @main
    struct Main {
        static func main() async throws {
            do {
                let data = try await fetchData()
                let str = String(data: data, encoding: .utf8)
                dump(str)
            } catch {
                print("** \(error.localizedDescription)")
            }
        }
    }

最佳答案

async/await环境中,可能的解决方案是Continuation来访问数据任务并能够观察进度 > 任务的属性。

fetchData 替换为

func fetchData() async throws -> Data {
    var observation: NSKeyValueObservation?
    // this is a 1 megabyte text file, big enough for updates
    let url = URL(string: "https://gist.github.com/khaykov/a6105154becce4c0530da38e723c2330/raw/41ab415ac41c93a198f7da5b47d604956157c5c3/gistfile1.txt")!
    return try await withCheckedThrowingContinuation { continuation in
        let _ = observation // to silence a warning
        let task = URLSession.shared.dataTask(with: url) { data, _, error in
            if let error {
                continuation.resume(throwing: error)
            } else {
                continuation.resume(returning: data!)
            }
        }
        observation = task.progress.observe(\.fractionCompleted) { progress, _ in
            print("progress: ", progress.fractionCompleted)
        }
        task.resume()
    }
}

关于swift - macOS 命令行代码在 Swift 中获取数据的现代方式,并带有进度通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77071929/

相关文章:

Swift - 加载横幅时更改应用程序。 - Xcode 6 通用汽车

ios - 完成社交分享后开始Segue

objective-c - 使用 Objective-C/pure C 使图像具有圆角

macos - Swift 3 中 tableView 函数的正确语法是什么? xCode 8 问题

objective-c - 将 NSData 中的字节解码为整数

azure - 重定向安全域是否需要两个域上的 ssl 证书?

html - 仅主页的 HTTPS 到 HTTP htaccess 重定向

php - 防止PHP中的session劫持、XSS和网络窃听?

IOS:如何使 ScrollView 仅在 subview 外部触摸时滚动?

ios - NSPredicate 用于多对多关系