无法将“(OpenAIChatResponse) async -> Void”类型的函数传递给需要具有两个函数的同步函数类型的参数

问题描述 投票:0回答:1

我有两个功能:

    @MainActor func sendMessage(messages: [Message], completion: @escaping (_ response: OpenAIChatResponse) -> Void) async {
        let openAIMessages = messages.map({OpenAIChatMessage(role: $0.role, content: $0.content)})
        let body = OpenAIChatBody(model: "gpt-3.5-turbo", messages: openAIMessages)
        var request = URLRequest(url: endpointUrl!)
        request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
        request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Accept")
        request.httpMethod = "POST"
        do {
            let encoded = try JSONEncoder().encode(body)
            request.httpBody = encoded
        } catch {
            print(error)
        }
        request.setValue("Bearer \(Constants.openAIApiKey)", forHTTPHeaderField: "Authorization")
        
        do {
            Task {
                let (data, _) = try await URLSession.shared.data(for: request)
                let responseData = try JSONDecoder().decode(OpenAIChatResponse.self, from: data)
                completion(responseData)
            }
        } catch NetworkError.badUrl {
            print("There was an error creating the URL")
        } catch NetworkError.badResponse {
            print("Did not get a valid response")
        } catch NetworkError.badStatus {
            print("Did not get a 2xx status code from the response")
        } catch NetworkError.failedToDecodeResponse {
            print("Failed to decode response into the given type")
        } catch {
            print("An error occured downloading the data")
        }
    }
        func sendMessage2(myMessage: String) {
            let newMessage = Message(id: UUID(), role: .user, content: myMessage, createAt: Date())
            messages.append(newMessage)
            Task {
                try await openAIService.sendMessage(messages: messages, completion: { response in
                    guard let receivedOpenAIMessage = response.choices?.first?.message else {
                        return
                    }
                    let receivedMessage = Message(id: UUID(), role: receivedOpenAIMessage.role, content: receivedOpenAIMessage.content, createAt: Date())
                    await MainActor.run {
                        messages.append(receivedMessage)
                    }
                })
            }
        }

但是我在尝试使用 sendMessage2 函数时收到错误:

Cannot pass function of type '(OpenAIChatResponse) async -> Void' to parameter expecting synchronous function type with two functions
。我只是转而使用completionHandlers 来尝试绕过async 和await 代码片段。但我不知道如何解决这个错误。这是它出现的位置的图像。这是什么错误以及如何消除它?

Error location

swift asynchronous swiftui completionhandler
1个回答
0
投票

不要混合完成处理程序和异步/等待并发框架。

仅使用异步/等待并发框架尝试此方法。

func sendMessage(messages: [Message]) async -> OpenAIChatResponse {
    let openAIMessages = messages.map{OpenAIChatMessage(role: $0.role, content: $0.content)}
    let body = OpenAIChatBody(model: "gpt-3.5-turbo", messages: openAIMessages)
    
    var request = URLRequest(url: endpointUrl!)
    request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
    request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Accept")
    request.httpMethod = "POST"
    do {
        let encoded = try JSONEncoder().encode(body)
        request.httpBody = encoded
    } catch {
        print(error)
    }
    request.setValue("Bearer \(Constants.openAIApiKey)", forHTTPHeaderField: "Authorization")
    
    do {
        let (data, _) = try await URLSession.shared.data(for: request)
        
        return try JSONDecoder().decode(OpenAIChatResponse.self, from: data)
        
    } catch NetworkError.badUrl {
        print("There was an error creating the URL")
    } catch NetworkError.badResponse {
        print("Did not get a valid response")
    } catch NetworkError.badStatus {
        print("Did not get a 2xx status code from the response")
    } catch NetworkError.failedToDecodeResponse {
        print("Failed to decode response into the given type")
    } catch {
        // todo deal with the error
        print(error)
    }
}

func sendMessage2(myMessage: String) async {
    let newMessage = Message(id: UUID(), role: .user, content: myMessage, createAt: Date())
    messages.append(newMessage)
    do {
        let response = try await sendMessage(messages: messages)
        guard let receivedOpenAIMessage = response.text else {
            return
        }
        let receivedMessage = Message(id: UUID(), role: receivedOpenAIMessage.role, content: receivedOpenAIMessage.content, createAt: Date())
        messages.append(receivedMessage)
    } catch {
        // todo deal with the error
        print(error)
    }
}
    
© www.soinside.com 2019 - 2024. All rights reserved.