命令行应用程序的 Swift 异步方法调用

发布于 2025-01-10 14:41:45 字数 783 浏览 0 评论 0原文

我正在尝试在简单的 Swift 命令行工具中重用一些在 SwiftUI 应用程序中运行良好的异步标记代码。 为了简单起见,我们假设我想

func fetchData(base : String) async throws -> SomeDate
    {
        let request = createURLRequest(forBase: base)
        
        let (data, response) = try await URLSession.shared.data(for: request)
        guard (response as? HTTPURLResponse)?.statusCode == 200 else {
            throw FetchError.urlResponse
        }
        let returnData = try! JSONDecoder().decode(SomeData.self, from: data)
        
        return returnData
    }

在命令行应用程序中重用一个函数。 像我的“main-function”中这样的调用

    let allInfo = try clerk.fetchData("base")

会给出错误消息'async' call in a function that does not support concurrency。 处理此案的正确方法是什么。

谢谢 帕特里克

I'm trying to reuse some async marked code that works great in a SwiftUI application in a simple Swift-Command line tool.
Lets assume for simplicity that I'd like to reuse a function

func fetchData(base : String) async throws -> SomeDate
    {
        let request = createURLRequest(forBase: base)
        
        let (data, response) = try await URLSession.shared.data(for: request)
        guard (response as? HTTPURLResponse)?.statusCode == 200 else {
            throw FetchError.urlResponse
        }
        let returnData = try! JSONDecoder().decode(SomeData.self, from: data)
        
        return returnData
    }

in my command line application.
A call like

    let allInfo = try clerk.fetchData("base")

in my "main-function" gives the error message 'async' call in a function that does not support concurrency.
What is the correct way to handle this case.

Thanks
Patrick

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我家小可爱 2025-01-17 14:41:45

要调用 async 方法,调用必须在 async 方法内部进行或包装在 Task 中。
此外,该方法必须调用 wirh await

Task {
    do {
        let allInfo = try await clerk.fetchData("base")
    } catch {
        print(error)
    }
}

您可以使用此语法使 CLI 的入口点 async

@main
struct CLI {
    static func main() async throws {

        let args = CommandLine.arguments
        ...
}

结构的名称是任意的。

您需要将文件从 main.swift 重命名为 CLI.swift 以修复错误“main”属性不能在包含顶级的模块中使用代码。

To call an async method the call must take place inside an async method or wrapped in a Task.
Further the method must be called wirh await

Task {
    do {
        let allInfo = try await clerk.fetchData("base")
    } catch {
        print(error)
    }
}

You can make the entry point of the CLI async with this syntax

@main
struct CLI {
    static func main() async throws {

        let args = CommandLine.arguments
        ...
}

The name of the struct is arbitrary.

You need to rename the file from main.swift to CLI.swift to fix the error 'main' attribute cannot be used in a module that contains top-level code.

入画浅相思 2025-01-17 14:41:45

如果您使用 Argument Parser 框架,那么从 1.0 版开始它支持异步上下文。您必须使您的结构符合 AsyncParsableCommand 协议。它创建可以安全运行异步函数的上下文。

If you are using Argument Parser framework then from version 1.0 it supports async context. You have to make your struct conforms to protocol AsyncParsableCommand. It creates context in which async function can be run safely.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文