Skip to content

Instantly share code, notes, and snippets.

@MainActor
struct ChatView: View {
@Bindable private var viewModel: ChatViewModel = ChatViewModel()
var body: some View {
NavigationStack {
VStack {
ChatMessagesList(viewModel: viewModel)
SendMessageButton {
Task {
await viewModel.sendMessage()
}
}
.disabled(!viewModel.canSendMessage)
struct ChatMessagesList: View {
@Bindable var viewModel: ChatViewModel
@State private var loadingViewId: UUID? = UUID()
var body: some View {
ScrollView {
ForEach(viewModel.messages) { message in
MessageCell(message: message)
.padding(message.role.padding)
import SwiftUI
struct ErrorView: View {
var body: some View {
Text("Something went wrong, please try sending your message again.")
.foregroundStyle(Color.red)
}
}
import SwiftUI
struct LoadingView: View {
var body: some View {
Image(systemName: "ellipsis.rectangle.fill")
.symbolRenderingMode(.hierarchical)
.foregroundStyle(Color.gray)
.font(.largeTitle)
.symbolEffect(.variableColor, options: .repeating, isActive: true)
@MainActor
@Observable
class ChatViewModel {
// Private
private let client: GeminiClient = GeminiClient()
// Public
var error: Error?
var waitingForResponse: Bool = false
@MainActor
@Observable
class ChatViewModel {
// Private
private let client: GeminiClient = GeminiClient()
// Public
var error: Error?
var waitingForResponse: Bool = false
import Foundation
import GoogleGenerativeAI
class GeminiClient {
private lazy var model = GenerativeModel(name: "gemini-pro", apiKey: APIKey.default)
private lazy var chat: Chat = model.startChat()
func send(message: String) async -> Result<String, GenerateContentError> {
do {
class GeminiClient {
enum APIKey {
// Fetch the API key from `GeminiChat.plist`
static var `default`: String {
guard let filePath = Bundle.main.path(forResource: "GeminiChat", ofType: "plist")
else {
fatalError("Couldn't find file 'GeminiChat.plist'.")
}
let plist = NSDictionary(contentsOfFile: filePath)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>API_KEY</key>
<string>123456789</string>
</dict>
</plist>