On the upcoming WWDC, Apple is predicted to announce an on-device massive language mannequin (LLM). The following model of the iOS SDK will doubtless make it simpler for builders to combine AI options into their apps. Whereas we await Appleās debut of its personal Generative AI fashions, corporations like OpenAI and Google already present SDKs for iOS builders to include AI options into cellular apps. On this tutorial, we’ll discover Google Gemini, previously often called Bard, and reveal the right way to use its API to construct a easy SwiftUI app.
We’re set to construct a Q&A app that makes use of the Gemini API. The app includes a easy UI with a textual content subject for customers to enter their questions. Behind the scenes, we’ll ship the consumerās query to Google Gemini to retrieve the reply.
Please be aware that it’s important to use Xcode 15 (or up) to comply with this tutorial.
Getting Began with Google Gemini APIs
Assuming that you simply havenāt labored with Gemini, the very very first thing is to go as much as get an API key for utilizing the Gemini APIs. To create one, you’ll be able to go as much as Google AI Studio and click on the Create API key button.
Utilizing Gemini APIs in Swift Apps
It is best to now have created the API key. Weāll use this in our Xcode undertaking. Open Xcode and create a brand new SwiftUI undertaking, which Iāll name GeminiDemo. To retailer the API key, create a property file named GeneratedAI-Data.plist
. On this file, create a key named API_KEY
and enter your API key as the worth.
To learn the API key from the property file, create one other Swift file named APIKey.swift
. Add the next code to this file:
guard let filePath = Bundle.essential.path(forResource: “GenerativeAI-Data”, ofType: “plist”)
else {
fatalError(“Could not discover file ‘GenerativeAI-Data.plist’.”)
}
let plist = NSDictionary(contentsOfFile: filePath)
guard let worth = plist?.object(forKey: “API_KEY”) as? String else {
fatalError(“Could not discover key ‘API_KEY’ in ‘GenerativeAI-Data.plist’.”)
}
if worth.begins(with: “_”) {
fatalError(
“Observe the directions at https://ai.google.dev/tutorials/setup to get an API key.”
)
}
return worth
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
enum APIKey { Ā Ā // Fetch the API key from `GenerativeAI-Data.plist` Ā Ā static var `default`: String { Ā Ā Ā Ā Ā guard let filePath = Bundle.essential.path(forResource: “GenerativeAI-Data”, ofType: “plist”) Ā Ā Ā Ā else { Ā Ā Ā Ā Ā Ā fatalError(“Could not discover file ‘GenerativeAI-Data.plist’.”) Ā Ā Ā Ā } Ā Ā Ā Ā Ā let plist = NSDictionary(contentsOfFile: filePath) Ā Ā Ā Ā Ā guard let worth = plist?.object(forKey: “API_KEY”) as? String else { Ā Ā Ā Ā Ā Ā fatalError(“Could not discover key ‘API_KEY’ in ‘GenerativeAI-Data.plist’.”) Ā Ā Ā Ā } Ā Ā Ā Ā Ā if worth.begins(with: “_”) { Ā Ā Ā Ā Ā Ā fatalError( Ā Ā Ā Ā Ā Ā Ā Ā “Observe the directions at https://ai.google.dev/tutorials/setup to get an API key.” Ā Ā Ā Ā Ā Ā ) Ā Ā Ā Ā } Ā Ā Ā Ā Ā return worth Ā Ā } } |
In the event you determine to make use of a unique identify for the property file as a substitute of the unique āGenerativeAI-Data.plistā, you have to to change the code in your āAPIKey.swiftā file. This modification is critical as a result of the code references the precise filename when fetching the API key. So, any change within the property file identify ought to be mirrored within the code to make sure the profitable retrieval of the API key.
Including the SDK Utilizing Swift Bundle
The Google Gemini SDK is well accessible as a Swift Bundle, making it easy so as to add to your Xcode undertaking. To do that, right-click the undertaking folder within the undertaking navigator and choose Add Bundle Dependencies. Within the dialog, enter the next bundle URL:
https://github.com/google/generative-ai-swift |
You may then click on on the Add Bundle button to obtain and incorporate theĀ GoogleGenerativeAI
Ā bundle into the undertaking.
Constructing the App UI
Letās begin with the UI. Itās easy, with solely a textual content subject for consumer enter and a label to show responses from Google Gemini.
Open ContentView.swift
and declare the next properties:
@State non-public var isThinking = false
@State non-public var textInput = “” @State non-public var response: LocalizedStringKey = “Whats up! How can I provide help to as we speak?” Ā @State non-public var isThinking = false |
The textInput
variable is used to seize consumer enter from the textual content subject. The response
variable shows the APIās returned response. Given the APIās response time, we embody an isThinking
variable to observe the standing and present animated results.
For the physique
variable, change it with the next code to create the consumer interface:
ScrollView {
VStack {
Textual content(response)
.font(.system(.title, design: .rounded, weight: .medium))
.opacity(isThinking ? 0.2 : 1.0)
}
}
.contentMargins(.horizontal, 15, for: .scrollContent)
Spacer()
HStack {
TextField(“Kind your message right here”, textual content: $textInput)
.textFieldStyle(.plain)
.padding()
.background(Coloration(.systemGray6))
.clipShape(RoundedRectangle(cornerRadius: 20))
}
.padding(.horizontal)
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
VStack(alignment: .main) { Ā Ā Ā Ā Ā ScrollView { Ā Ā Ā Ā Ā Ā Ā Ā VStack { Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Textual content(response) Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā .font(.system(.title, design: .rounded, weight: .medium)) Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā .opacity(isThinking ? 0.2 : 1.0) Ā Ā Ā Ā Ā Ā Ā Ā } Ā Ā Ā Ā } Ā Ā Ā Ā .contentMargins(.horizontal, 15, for: .scrollContent) Ā Ā Ā Ā Ā Spacer() Ā Ā Ā Ā Ā HStack { Ā Ā Ā Ā Ā Ā Ā Ā Ā TextField(“Kind your message right here”, textual content: $textInput) Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā .textFieldStyle(.plain) Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā .padding() Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā .background(Coloration(.systemGray6)) Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā .clipShape(RoundedRectangle(cornerRadius: 20)) Ā Ā Ā Ā Ā } Ā Ā Ā Ā .padding(.horizontal) } |
The code is kind of easy, particularly when you have some expertise with SwiftUI. After making the modifications, it’s best to see the next consumer interface within the preview.
Integrating with Google Gemini
Earlier than you need to use the Google Gemini APIs, you first have to import the GoogleGenerativeAI
module:
import GoogleGenerativeAI |
Subsequent, declare a mannequin
variable and initialize the Generative mannequin like this:
let mannequin = GenerativeModel(identify: “gemini-pro”, apiKey: APIKey.default) |
Right here, we make the most of the gemini-pro
mannequin, which is particularly designed to generate textual content from textual content enter.
To ship the textual content to Google Gemini, letās create a brand new perform known as sendMessage()
:
withAnimation(.easeInOut(period: 0.6).repeatForever(autoreverses: true)) {
isThinking.toggle()
}
Activity {
do {
let generatedResponse = strive await mannequin.generateContent(textInput)
guard let textual content = generatedResponse.textual content else {
textInput = “Sorry, Gemini bought some issues.nPlease strive once more later.”
return
}
textInput = “”
response = LocalizedStringKey(textual content)
isThinking.toggle()
} catch {
response = “One thing went incorrect!n(error.localizedDescription)”
}
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
func sendMessage() { Ā Ā Ā Ā response = “Pondering…” Ā Ā Ā Ā Ā withAnimation(.easeInOut(period: 0.6).repeatForever(autoreverses: true)) { Ā Ā Ā Ā Ā Ā Ā Ā isThinking.toggle() Ā Ā Ā Ā } Ā Ā Ā Ā Ā Activity { Ā Ā Ā Ā Ā Ā Ā Ā do { Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā let generatedResponse = strive await mannequin.generateContent(textInput) Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā guard let textual content = generatedResponse.textual content elseĀ Ā { Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā textInput = “Sorry, Gemini bought some issues.nPlease strive once more later.” Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā return Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā } Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā textInput = “” Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā response = LocalizedStringKey(textual content) Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā isThinking.toggle() Ā Ā Ā Ā Ā Ā Ā Ā } catch { Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā response = “One thing went incorrect!n(error.localizedDescription)“ Ā Ā Ā Ā Ā Ā Ā Ā } Ā Ā Ā Ā } } |
As you’ll be able to see from the code above, you solely have to name the generateContent technique of the mannequin to enter textual content and obtain the generated response. The result’s in Markdown format, so we use LocalizedStringKey
to wrap the returned textual content.
To name the sendMessage()
perform, replace the TextField
view and fix the onSubmit
modifier to it:
TextField(“Kind your message right here”, textual content: $textInput) Ā Ā Ā Ā .textFieldStyle(.plain) Ā Ā Ā Ā .padding() Ā Ā Ā Ā .background(Coloration(.systemGray6)) Ā Ā Ā Ā .clipShape(RoundedRectangle(cornerRadius: 20)) Ā Ā Ā Ā .onSubmit { Ā Ā Ā Ā Ā Ā Ā Ā sendMessage() Ā Ā Ā Ā } |
On this state of affairs, when the consumer finishes inputting the textual content and presses the return key, the sendMessage()
perform is named to submit the textual content to Google Gemini.
Thatās it! Now you can run the app in a simulator or execute it instantly within the preview to check the AI function.
Abstract
This tutorial exhibits the right way to combine Google Gemini AI right into a SwiftUI app. It solely requires just a few traces of code to allow your app with Generative AI options. On this demo, we use the gemini-pro
mannequin to generate textual content from text-only enter.
Nevertheless, the capabilities of Gemini AI are usually not simply restricted to text-based enter. Gemini additionally affords a multimodal mannequin named gemini-pro-vision
that permits builders to enter each textual content and pictures. We encourage you to take full benefit of this tutorial by modifying the supplied code and experimenting with it.
If in case you have any questions concerning the tutorial, please let me know by leaving a remark under.