Reputation: 38
I have two functions:
@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)
}
})
}
}
But I am getting the error: Cannot pass function of type '(OpenAIChatResponse) async -> Void' to parameter expecting synchronous function type with two functions
when trying to use the sendMessage2 function. I just switched to using completionHandlers to try and get around the async and await pieces of code. But I don't know how to resolve this error. Here is an image of where it shows up. What is this error and how do I get rid of it?
Upvotes: 0
Views: 289
Reputation: 37050
Do not mix completion handlers and the async/await concurrency framework.
Try this approach using only the async/await concurrency framework.
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)
}
}
And call it like this await sendMessage2(myMessage: "Hello")
Upvotes: 0