Проблема с декодированием вызовов Swift API: ошибка декодирования

На прошлой неделе я сделал приложение

После небольшой "отладки" я получил эту ошибку:

сбой (OpenAISwift.OpenAIError.decodingError (ошибка: Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "объект", intValue: ноль), Swift.DecodingError.Context(codingPath: [], debugDescription: "Нет значения, связанного с ключом CodingKeys(stringValue: "объект", intValue: nil) ("объект").", основная ошибка: ноль))))

Код, который я использую, почти такой же, как в видео, с той лишь разницей, что я обрезаю пробелы и новые строки (это не та проблема, которую я проверял)

Мой код (с ошибкой) выглядит так:

import OpenAISwift
import SwiftUI    
final class ViewModel: ObservableObject{
    init(){}
    
    private var client: OpenAISwift?
    
    func setup(){
        client = OpenAISwift(authToken: "MY_API_KEY")
    }
    
    func makeCall(text: String,
                  completion: @escaping (String) -> Void){
        client?.sendCompletion(with: text,
                               maxTokens: 500,
                               completionHandler: { result in
            switch result {
            case .success(let model):
                let output = model.choices.first?.text.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
                completion(output)
            case .failure:
                print("Failed: \(result)")
                break
            }
        })
    }
}

Я надеюсь, что кто-то может помочь мне с этим, потому что все, что я пробовал, не помогло. Я пытался использовать другие методы вызова API, но это тоже не сработало... Так что, если вы знаете, в чем проблема и как ее решить, пожалуйста, дайте мне знать

Изменить код завершения отправки:

public func sendCompletion(with prompt: String, model: OpenAIModelType = .gpt3(.davinci), maxTokens: Int = 16, temperature: Double = 1, completionHandler: @escaping (Result<OpenAI<TextResult>, OpenAIError>) -> Void) {
    let endpoint = Endpoint.completions
    let body = Command(prompt: prompt, model: model.modelName, maxTokens: maxTokens, temperature: temperature)
    let request = prepareRequest(endpoint, body: body)

makeRequest(request: request) { result in
    switch result {
    case .success(let success):
        do {
            let res = try JSONDecoder().decode(OpenAI<TextResult>.self, from: success)
            completionHandler(.success(res))
        } catch {
            completionHandler(.failure(.decodingError(error: error)))
        }
    case .failure(let failure):
        completionHandler(.failure(.genericError(error: failure)))
    }
}

}

Изменить после обратной связи:

Я обновил версию, и после этого она перестала выдавать мне эту ошибку, но теперь выдает другую.... вот эту:

успех(OpenAISwift.OpenAI<OpenAISwift.TextResult>(объект: ноль, модель: ноль, выбор: ноль, использование: ноль, данные: ноль))

Ошибка связана с декодированием json, но опубликованный вами код не имеет ничего общего с декодированием json.

Joakim Danielson 04.04.2023 13:19

@JoakimDanielson, я случайно нажал клавишу ввода, когда создавал этот заголовок. Я поменял как можно быстрее.

Niels040 04.04.2023 13:20

Что бы тогда помогло? Потому что здесь что-то идет не так

Niels040 04.04.2023 13:27
sendCompletion(with:maxTokens:completionHandler:) я думаю, где есть видимый JSONDecoder с (De)Codable моделью или скрытый с помощью Alamofire с responseDecodable(of:), и где вы получите реальный результат API, это очень поможет!. В настоящее время это все равно, что сказать, что на кухне есть утечка, но показать только переднюю часть дома и спросить, что можно сделать, чтобы ее устранить.
Larme 04.04.2023 13:27

@Larme Я отредактировал его, содержащий код sendCompletion

Niels040 04.04.2023 13:32

Я думаю, вы вводите completionHandler(.failure(.decodingError(error: error)))? Если success это Data, как я думаю, делайте print("Response received: \(String(data: success, encoding: .utf8)") Я думаю, ответ не тот, который вы ожидаете

Larme 04.04.2023 13:34

@Larme, так я ничего не могу сделать?

Niels040 04.04.2023 13:52

Распечатайте полученный ответ и поделитесь им. Кажется, вы получили другой ответ JSON. Почему? Я не знаю. Может быть обновление на бэкэнде, вы используете последнюю версию библиотеки?

Larme 04.04.2023 14:04

@Larme Я не могу напечатать / отредактировать файл из ...

Niels040 04.04.2023 14:14

OpenAI настоятельно рекомендует разработчикам прокси-запросов клиентских приложений через отдельную серверную службу для обеспечения безопасности своего ключа API. Ключи API могут получать доступ к счетам клиентов, их использованию и организационным данным и управлять ими.

lorem ipsum 04.04.2023 17:06
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
10
215
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Попробуйте этот пример кода, он хорошо работает для меня, если ваш YOUR-APIKEY действителен. Дайте мне знать, если это не работает для вас.

Обратите внимание, используйте последнюю ветку mainOpenAISwift, а не другие версии или теги.

import Foundation
import SwiftUI
import OpenAISwift


@MainActor
class OpenAIModel: ObservableObject {
    
    @Published var answers = [String]()
    
    let client: OpenAISwift
    
    init() {
        client = OpenAISwift(authToken: "YOUR-APIKEY")
    }
    
    func ask(text: String) async {
        do {
            let result = try await client.sendCompletion(
                with: text,
                model: .gpt3(.davinci),
                maxTokens: 500,
                temperature: 1
            )
            let output = result.choices?.first?.text ?? "no answer"
            answers.append(output)
        } catch {
            print(error)
        }
    }
    
    func makeCall(text: String, completion: @escaping (String) -> Void) {
        client.sendCompletion(with: text, maxTokens: 500) { result in
            switch result {
            case .success(let model):
                let output = model.choices?.first?.text.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
                completion(output)
            case .failure:
                print("---> Failed: \(result)")
                completion("Failed")
                break
            }
        }
    }
    
}

struct ContentView: View {
    @StateObject var openAI = OpenAIModel()
    let text = "explain Schrödinger's wave equation"
    
    var body: some View {
        VStack {
            Text("fetching...")
            ForEach(openAI.answers, id: \.self) { answer in
                Text(answer)
            }
        }
        .onAppear {
            openAI.makeCall(text: text){ answer in
                DispatchQueue.main.async {
                    openAI.answers.append(answer)
                }
            }
        }
//        .task{
//            await openAI.ask(text: text)
//        }
    }
}

Также обратите внимание, что по адресу: https://github.com/adamrushy/OpenAISwift/issues/28 сообщается об ошибке в декодировании, она может иметь отношение к вашему делу.

Я использовал ваш MakeCall, но с этим и моим собственным кодом после обновления я получаю эту ошибку: успех (OpenAISwift.OpenAI<OpenAISwift.TextResult> (объект: ноль, модель: ноль, выбор: ноль, использование: ноль, данные: ноль ))

Niels040 05.04.2023 09:21

И как вопрос о вашем коде, вы делаете функцию запроса, но никогда ее не используете... потому что она закомментирована. эта функция нужна?

Niels040 05.04.2023 09:33

ок, ваш первый комментарий, мой код хорошо работает для меня, когда есть ключ API valid. Я подозреваю, что у вас должен быть другой код, который неверен и, таким образом, дает вам некоторые ошибки. Попробуйте мой код как есть и дайте мне знать, если он работает. Re, ваш второй комментарий, используя ask(), должен показать альтернативный способ сделать все это, используя более новый параллелизм Swift (async/await), поэтому он прокомментирован. Используйте тот или иной. Какой вклад text в makeCall вы пробовали?

workingdog support Ukraine 05.04.2023 09:52

Я использовал весь ваш код, я не думаю, что он работает для меня, потому что он говорит только о извлечении .... Я использовал ДЕЙСТВИТЕЛЬНЫЙ ключ API, так где я должен проверить, что он испортился? С помощью функции запроса добавляется «Нет ответа».

Niels040 05.04.2023 09:58

нужно дождаться ответа. Попробуйте мой код еще раз, пожалуйста.

workingdog support Ukraine 05.04.2023 10:04

Я подожду, за последние 5 минут он все еще не появился, и когда я попытался отладить его с помощью print(result), я получил ту же ошибку, что и с моим собственным кодом, OpenAI<TextResult>(object: nil, model: ноль, выбор: ноль, использование: ноль, данные: ноль)

Niels040 05.04.2023 10:05

это должно занять всего 5-10 секунд. Не могу понять, как это не работает для вас только с моим кодом.

workingdog support Ukraine 05.04.2023 10:08

Основная проблема в том, что я получаю только ноль. Я переделал ключ API, чтобы он работал, но он все еще возвращает ноль. Так что не знаю, как это исправить. Я думаю, что проблема не в вашем коде, а в чем проблема...

Niels040 05.04.2023 10:12

новый ключ, ибо gpt3 это правильно, а не gpt4

workingdog support Ukraine 05.04.2023 10:14

да gpt3, я использовал эту ссылку platform.openai.com/account/api-keys

Niels040 05.04.2023 10:17

не видно в чем проблема. Я также сгенерировал новый ключ, и он тоже работает.

workingdog support Ukraine 05.04.2023 10:21

Обратите внимание, убедитесь, что вы отметили Outgoing Connections (client) в App Sandbox в Signing & Capabilities.

workingdog support Ukraine 05.04.2023 11:02

После некоторой работы над этим, он решил работать. Так плохо сделать это ответ. Спасибо

Niels040 05.04.2023 11:23

Другие вопросы по теме