SwiftUIでGeminiAIを使おう!
やること
SwiftUIでGeminiAIを使う
筆者の環境
Mac os Sonoma 14.3.1
Xcode 15.3
GeminiAPIの実装がドチャクソ簡単だったので記録として残しておきます。
そもそもGeminiとは?
Geminiは、Googleが開発した大規模言語モデル(LLM)および人工知能(AI)システムです。
APIキーを取得
まずはGeminiAIを使うためにAPIキーを取得します。
GoogleAIStudioに行ってください
そうしたら左側のメニューバーにGet API Keyがあるのでそこをクリックしてください。
APIキーを作成と書いてあるのでクリックしてAPIKeyを作成しましょう (筆者の画像を 日本語訳がなんかバグっていてキーAPIキーを作成となっていますが気にしないでください)
そこから進めていくとAPIキーを作成できると思うのでキーをコピーしてください。
実装
進めていくにあたって公式のドキュメントに沿って進んでいきます。
Gemini SDKをインストール
Xcodeで新しいプロジェクトを作成してください。
まずはGeminiのSDKをインストールしましょう。
Xcodeの右上から File > Add Package Dependencies
で Search or Enter Package URL に以下のリンクを貼り付けてください
"https://github.com/google/generative-ai-swift"
貼り付けたら Add Packageを押して追加してください。
GenerativeAI-Info.plist作成
次は GenerativeAI-Info.plist を作成します。
File > New > File から Property Listを作成してください。
ファイル名は GenerativeAI-Info
そうしたらこの画像のようになると思うので Infomation Property Listにカーソルを合わせると
小さいプラスマークが出てくると思うのでそれをクリック
API_KEY と入力してその値に先ほど作成したAPIキーを入れてください。
これで完了です。
APIKeyファイルの作成
File > New > File から Swiftファイルを作成してください。
作成したら下記のコードをコピーして貼り付けてください。
import Foundation
enum APIKey {
// Fetch the API key from `GenerativeAI-Info.plist`
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: "_") {
fatalError(
"Follow the instructions at https://ai.google.dev/tutorials/setup to get an API key."
)
}
return value
}
}
ContentViewの実装
下記のコードをまるパクリでOKです。
import SwiftUI
import GoogleGenerativeAI
struct ContentView: View {
let model = GenerativeModel(name: "gemini-1.5-flash", apiKey: APIKey.default)
@State var Prompt = ""
@State var Respons = ""
@State var isLoading = false
var body: some View {
ZStack {
VStack {
Text("Hello I am Gemini")
.font(.title2)
.fontWeight(.bold)
Text("何かお手伝いすることはありますか?")
.fontWeight(.bold)
Spacer()
ScrollView {
Text(Respons)
.font(.title3)
.fontWeight(.semibold)
}
Spacer()
HStack {
TextField("Aa", text: $Prompt)
.textFieldStyle(.roundedBorder)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.padding()
Button(action: {
generateRespons()
}){
Image(systemName: "arrow.up")
.frame(width: 40, height: 40)
.background(Color.green)
.foregroundColor(.white)
.clipShape(Circle())
}.padding()
}
}
if isLoading {
Color.black.opacity(0.3)
ProgressView()
}
}
}
func generateRespons() {
isLoading = true
Respons = ""
Task {
do {
let result = try await model.generateContent(Prompt)
isLoading = false
Respons = result.text ?? "No Respons found"
Prompt = ""
} catch {
Respons = "Sometimes went wrong \n \(error.localizedDescription)"
isLoading = false
Prompt = ""
}
}
}
}
#Preview {
ContentView()
}
こうなっていたらOKです。
参考記事や動画
最後
GeminiAIがこんな簡単に実装できるとは思っていませんでした。
最後まで読んでいただきありがとうございました🙇
Discussion