Help with this code

Im trying to write a code where I can use a chat bot interacting with a app, but I always receive 3 errors and I cant solve this

import SwiftUI
import OpenAISwift

struct ContentView: View {
State private var calories: Int = 0
let goalCalories = 2000
State private var textInput: String = ""
State private var showDietaView: Bool = false
State private var showChatbotView: Bool = false
State private var apiKey: String = "your-api-key" // Replace with your actual API key

var body: some View {
    VStack {
        Circle()
            .frame(width: 250, height: 250)
            .foregroundColor(.blue)
            .overlay(
                Text("\(calories)/\(goalCalories) Kcal")
                    .font(.system(size: 30))
                    .foregroundColor(.white)
            )
            .padding(.top, 50)

        Spacer()

        Spacer()

        Rectangle()
            .frame(maxWidth: .infinity)
            .frame(height: 300)
            .foregroundColor(.gray)
            .overlay(
                TextField("Type something...", text: $textInput)
                    .padding()
            )
            .padding(.horizontal)
            .padding(.bottom, 20)
    }
    .padding(.bottom, 20)

    HStack {
        Button(action: {
            // Action to display the DietaView
            showDietaView = true
        }) {
            Text("Shortcut 2")
                .padding()
                .foregroundColor(.white)
        }
        .sheet(isPresented: $showDietaView) {
            DietaView()
        }

        Button(action: {
            // Action to display the food view
        }) {
            Text("Shortcut 3")
                .padding()
                .foregroundColor(.white)
        }

        Button(action: {
            // Action to display the chatbot
            showChatbotView = true
        }) {
            Text("Shortcut 4")
                .padding()
                .foregroundColor(.white)
        }
        .sheet(isPresented: $showChatbotView) {
            ChatbotView(apiKey: apiKey) // Passing the API key to the chatbot view
        }
    }
    .padding()
    .frame(maxWidth: .infinity)
    .background(Color.blue)
}

}

struct DietaView: View {
var body: some View {
Text("Tabela de Dieta")
}
}

struct ChatbotView: View {
StateObject private var viewModel: ChatbotViewModel

init(apiKey: String) {
    self._viewModel = StateObject(wrappedValue: ChatbotViewModel(apiKey: apiKey))
}

var body: some View {
    VStack {
        ScrollView {
            ForEach(viewModel.chatHistory) { message in
                ChatBubble(text: message.text, isUserMessage: message.isUserMessage)
            }
        }
        .padding()

        TextField("Type a message", text: $viewModel.currentMessage)
            .textFieldStyle(RoundedBorderTextFieldStyle())
            .padding()

        Button(action: viewModel.sendMessage) {
            Text("Send")
                .padding()
                .foregroundColor(.white)
                .background(Color.blue)
                .cornerRadius(10)
        }
        .padding()
    }
}

}

class ChatbotViewModel: ObservableObject {
Published var chatHistory: [ChatMessage] =
Published var currentMessage: String = ""
let apiKey: String

init(apiKey: String) {
    self.apiKey = apiKey
}

func sendMessage() {
    let userMessage = ChatMessage(text: currentMessage, isUserMessage: true)
    chatHistory.append(userMessage)

    let prompt = """
    You are a user.
    User: \(currentMessage)
    Bot:
    """

    let openAI = OpenAI(apiKey: apiKey)

    openAI.completion(
        prompt: prompt,
        maxTokens: 60
    ) { result in
        switch result {
        case .success(let response):
            do {
                let decoder = JSONDecoder()
                let responseData = try JSONSerialization.data(withJSONObject: response, options: [])
                let chatResponse = try decoder.decode(Response.self, from: responseData)
                
                if let text = chatResponse.choices.first?.text {
                    DispatchQueue.main.async {
                        let botMessage = ChatMessage(text: text.trimmingCharacters(in: .whitespacesAndNewlines), isUserMessage: false)
                        self.chatHistory.append(botMessage)
                    }
                }
            } catch {
                print("Error decoding response: \(error)")
            }
        case .failure(let error):
            print("Error: \(error)")
        }
    }

    currentMessage = ""
}

}

struct ChatBubble: View {
let text: String
let isUserMessage: Bool

var body: some View {
    HStack {
        if isUserMessage {
            Spacer()
            Text(text)
                .padding()
                .background(Color.blue)
                .foregroundColor(.white)
                .cornerRadius(10)
        } else {
            Text(text)
                .padding()
                .background(Color.gray)
                .foregroundColor(.white)
                .cornerRadius(10)
            Spacer()
        }
    }
    .padding(.vertical, 5)
}

}

struct ChatMessage: Identifiable {
let id = UUID()
let text: String
let isUserMessage: Bool
}

struct Response: Codable {
let choices: [Choice]
}

struct Choice: Codable {
let text: String
}

main
struct YourApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}

this is the code and I always received this 3 errors Argument type 'String' does not conform to expected type 'Decoder'; Generic parameter 'T' could not be inferred; Incorrect argument label in call (have 'apiKey:', expected 'from:')

When posting code snippets here embed them in triple back ticks ``` so they are formatted sanely.

I'd recommend reducing this app down to a one / two lines of code that reproduces the compilation issue. More than likely it's not related to SwiftUI, so you could well do it in a standalone function without any SwiftUI shenanigans. You can perform this separately for the three issues (could well be the case that's just one issue that's result into three errors). By the end of this exercise you'd more than likely find the issue(s) yourself, or just paste the resulting two lines here so we could have a look and suggest the fix.

7 Likes