'Access data of of struct swift
I am trying to display the response after making a post request to a GPT3 open ai endpoint.
Here is an example JSON response:
{
"id": "cmpl-4R7o3DcLSOGjjWHs5CrKXecNAoRDL",
"object": "text_completion",
"created": 1642370211,
"model": "davinci:2020-05-03",
"choices": [
{
"text": "\n\nA neutron star is a star that is so dense that it has collapsed into a sphere.\n\nA neutron star is the collapsed core of a massive supergiant star, which had a total mass of between 10 and 25 solar masses, possibly more if the star was especially metal-rich",
"index": 0,
"logprobs": null,
"finish_reason": "length"
}
]
}
I specifically want to display the text of the response. To do this i have created two structs in line with what https://app.quicktype.io/ returns for plain types.
struct Response: Codable, Identifiable{
var id = String()
var model = String()
var choices: [Choice]
}
struct Choice: Codable{
var finish_reason = String()
var index = Int()
var text = String()
}
I then created a class to call the endpoint, decode the JSON and return the data via a completion handler:
class GPT3TextComepletion: ObservableObject{
@Published var response = Response.self
func textCompletion(promptText:String, completion:@escaping (Response) -> ()) {
let token = "redacted"
let url = URL(string: "https://api.openai.com/v1/engines/davinci/completions")!
// prepare json data
var json: [String: Any] = [
"temperature": 0.7,
"max_tokens": 60,
"top_p": 1.0,
"frequency_penalty": 0,
"presence_penalty": 0]
json["prompt"] = promptText
let jsonData = try? JSONSerialization.data(withJSONObject: json)
// create post request
var request = URLRequest(url: url)
request.httpMethod = "POST"
// insert json data to the request
request.httpBody = jsonData
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.setValue( "Bearer \(token)", forHTTPHeaderField: "Authorization")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print(error?.localizedDescription ?? "No data")
return
}
let response = try! JSONDecoder().decode(Response.self, from: data)
let choice = response.choices
print(choice)
DispatchQueue.main.async {
completion(response)
}
}
task.resume()
}
}
I can access any data that is not in choice array i.e model via this:
@State var response: Response? = nil
Button(action: {GPT3TextComepletion().textCompletion(promptText: prompt, completion: {(response) in self.response = response })})
Text(response?.model ?? "some data")
However I have not been able to access the data from the choice struct(i can print the data just not display it). The error I am recieving i:
Initializer 'init(_:)' requires that 'Choice' conform to 'StringProtocol'
Due to the Choice struct being an array i have tried iterating over it with no success or accessing the third element of the array:
Text(response!.choices[2])
I would like to display the data(specifically the text variable) from the choice struct if anyone can assist.
Thanks!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
