Home > Back-end >  Access data of of struct swift
Access data of of struct swift

Time:01-25

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!

CodePudding user response:

Text(response!.choices[2])

This line returns a Choice struct which is not a string representable. You need to go a level deeper and access it's text property.

Text(response!.choices[2].text)

I assume you have hardcoded and forced unwrapped for the example's sake. Otherwise follow safe coding practices :)

  •  Tags:  
  • Related