Seamless Synergy: Gemini AI Integration in Your iOS App Using SwiftUI

Meet Patel 
4 min readJan 4, 2024

--

Gemini AI

Google released the Gemini SDK for developers. This is a cutting-edge family of multimodal large language models developed by Google DeepMind. Released in December 2023, it’s considered a successor to previous AI powerhouses like LaMDA and PaLM 2. For this post, we’ll look at text-only inputs with the Gemini Pro model. You will need Xcode 15.0 at minimum with the app target set to iOS 15/MacOS 12 or later.

  • Please create a new Xcode project, Let's call it GeminiChat.
  • Go to File > Add Package Dependencies... and enter the following URL in the search bar. This will fetch the generative-ai-swift SPM package to integrate with our Xcode project.
https://github.com/google/generative-ai-swift
  • Click Add Package in the subsequent steps to complete integration.
  • To work with the API and to make requests with Gemini, you need an API KEY. So head over to the Google AI Studio website:
https://makersuite.google.com/app/apikey
  • Next, click on the Create API key in new project option. A new dialog will show with the generated API key, so Copy it.
  • Next, back in Xcode select File > New File > Property List. You could name the file whatever you want, I went with GenerativeAI-Info.
  • Add a key-value pair with the name API_KEY and the value as the String API key that you copied from step #5 above. You should ignore this file in source control so as not to expose the API key in public.
  • Next, create a new Swift file with the name APIKey and paste the following:

This code looks for the API key inside the plist to pass it onto the generative model in the next steps. Remember to replace GenerativeAI-Info.plist if you provided a different file name in step #6.

import Foundation

enum APIKey {
/// Fetch the API key from `GenerativeAI-Info.plist`
/// This is just *one* way how you can retrieve the API key for your app.
static var `default`: String {
guard let filePath = Bundle.main.path(forResource: "GenerativeAI-Info", ofType: "plist")
else {
fatalError("Couldn't find file 'GenerativeAI-Info.plist'.")
}
let plist = NSDictionary(contentsOfFile: filePath)
guard let value = plist?.object(forKey: "API_KEY") as? String else {
fatalError("Couldn't find key 'API_KEY' in 'GenerativeAI-Info.plist'.")
}
if value.starts(with: "_") || value.isEmpty {
fatalError(
"Follow the instructions at https://ai.google.dev/tutorials/setup to get an API key."
)
}
return value
}
}
  • Switch to ContentView.swift and import the GoogleAI module below the import SwiftUI statement.
import GoogleGenerativeAI
  • The complete code looks like this:
ScrollViewReader { scrollViewProxy in
List {
ForEach(viewModel.messages) { message in
MessageView(message: message)
}
if let error = viewModel.error {
ErrorView(error: error)
.tag("errorView")
}
}
.listStyle(.plain)
.onChange(of: viewModel.messages, perform: { newValue in
if viewModel.hasError {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
withAnimation {
scrollViewProxy.scrollTo("errorView", anchor: .bottom)
}
focusedField = .message
}
} else {
guard let lastMessage = viewModel.messages.last else { return }
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
withAnimation {
scrollViewProxy.scrollTo(lastMessage.id, anchor: .bottom)
}
focusedField = .message
}
}
})
}
HStack {
TextField("Type your message...", text: $userPrompt)
.padding()
.accentColor(.white)

Button {
sendMessage()
} label: {
Image(systemName: userPrompt == "" ? "" : "arrow.up.circle.fill")
.resizable()
.scaledToFit()
.frame(width: 25, height: 25)
.scaleEffect(userPrompt == "" ? 1.0 : 1.3)
.foregroundColor(userPrompt == "" ? .white.opacity(0.6) : .white)
.padding()
}
.disabled(userPrompt == "")
.focused($focusedField, equals: .message)
.onSubmit { sendOrStop() }
.submitLabel(.done)
}
.background(.gray.opacity(0.2))
.cornerRadius(8)
.padding()
private func sendMessage() {
Task {
let prompt = userPrompt
userPrompt = ""
await viewModel.sendMessage(prompt, streaming: true)
}
}

private func sendOrStop() {
if viewModel.busy {
viewModel.stop()
} else {
sendMessage()
}
}
  • Finally, enter some input for the AI and wait for the response.

You can see the video demo:- YouTube

Note:- Contact me if you want the code:- patelmeet0809@gmail.com

Consider subscribing to my YouTube channel & follow me on X(Twitter), Linkedin, and GitHub for more such information. Leave a comment if you have any questions.

Clap 👏 and share this article if you found it useful!

See you in our next article!

--

--

Meet Patel 

Hey there 👋 , I'm an Expert in iOS & Flutter App Development. | Freelancer