访问结构 swift 的数据

Access data of of struct swift

我在向 GPT3 open ai 端点发出 post 请求后尝试显示响应。

这是一个示例 JSON 响应:

{
    "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"
        }
    ]
}

我特别想显示响应的文本。为此,我创建了两个符合 https://app.quicktype.io/ return 普通类型的结构。

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()
    
}

然后我创建了一个 class 来调用端点,通过完成处理程序解码 JSON 和 return 数据:

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()
    }
}

我可以访问任何不在选择数组中的数据,即通过此模型:

    @State var response: Response? = nil
          Button(action: {GPT3TextComepletion().textCompletion(promptText: prompt, completion: {(response) in self.response = response })}) 
Text(response?.model ?? "some data")

但是我无法从选择结构访问数据(我可以打印数据但不显示它)。我收到的错误是:

Initializer 'init(_:)' requires that 'Choice' conform to 'StringProtocol'

由于 Choice 结构是一个数组,我尝试对其进行迭代但没有成功或访问数组的第三个元素:

 Text(response!.choices[2])

如果有人可以提供帮助,我想显示选择结构中的数据(特别是文本变量)。

谢谢!

Text(response!.choices[2])

这一行 returns 一个不能用字符串表示的 Choice 结构。您需要更深入地访问它的文本 属性.

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

我假设您为了示例的缘故进行了硬编码和强制解包。否则请遵循安全编码实践:)