SwiftUI 框架

如何使用 Swift 整合 Google Gemini AI

如何使用 Swift 整合 Google Gemini AI
如何使用 Swift 整合 Google Gemini AI
In: SwiftUI 框架, AI

在即將到來的 WWDC,Apple 預計將會發佈一個本地端的大型語言模型 (LLM)。 接下來的 iOS SDK 版本將讓開發者更輕易地整合 AI 功能至他們的應用程式中。然而,當我們正在等待 Apple 推出自家的生成 AI 模型時,其他公司(如 OpenAI 和 Google)已經提供了 SDK 讓 iOS 開發者能將 AI 功能納入移動應用程式。在這篇教學中,我們將探討 Google Gemini,也就是之前的 Bard,並示範如何使用其 API 來建立一個簡單的 SwiftUI 應用程式。

我們打算製作一個使用 Gemini API 的問答應用程式。這個 App 有著簡單的使用者介面 - 就只有一個讓使用者輸入問題的文字框和顯示回覆文字的 View。看似簡單,但在背後,我們是將使用者的問題發送至 Google Gemini 並取得解答。

請注意,你必須使用 Xcode 15 (或以上版本) 來跟隨這份教學。

開始使用 Google Gemini APIs

假設你從未使用過 Gemini,首要之事是取得一個用於使用 Gemini APIs 的 API 金鑰。為了建立一個,你可以到 Google AI Studio 並點擊 創建 API 金鑰 按鈕。

在 Swift App 開發中使用 Gemini APIs

你現在應該已經製作了 API 金鑰。我們會在我們的 Xcode 專案中使用它。開啟 Xcode 並且創建一個新的 SwiftUI 專案,我將它命名為 GeminiDemo。為了儲存 API 金鑰,創建一個名為 GeneratedAI-Info.plist 的屬性檔案。在此檔案中,創建一個名為 API_KEY 的金鑰並將你的 API 金鑰作為其值輸入。

為了從屬性檔案讀取 API 金鑰,創建另一個名為 APIKey.swift 的 Swift 檔案。將以下的程式碼加入此檔案:

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
  }
}

如果你決定使用一個與原始的 GenerativeAI-Info.plist 不同的屬性檔案名稱,你將需要修改你的 APIKey.swift 檔案中的程式碼。這個修改是必需的,因為程式碼在獲取 API 金鑰時參考了特定的檔案名稱。因此,任何改變屬性檔案名稱的動作都應該在程式碼中反映出來,以確保成功獲取 API 金鑰。

使用 Swift Package 添加 SDK

Google Gemini SDK 可以輕易地以 Swift Package 的形式取得,你可以很方便地將它加入至你的 Xcode 專案中。要做到這點,只需要在專案導覽器中右鍵點擊你的專案資料夾,並選擇添加封包依賴。在彈出的對話框中,輸入以下的封包 URL:

https://github.com/google/generative-ai-swift

之後,你可以點擊添加封包按鈕來下載並將 GoogleGenerativeAI 封包加入進專案內。

建立應用程式的使用者介面

讓我們從使用者介面開始。這個實作相對簡單,只有一個用來讓使用者輸入的文字欄位以及一個用來展示 Google Gemini 回應的標籤。

打開 ContentView.swift 並宣告以下的屬性:

@State private var textInput = ""
@State private var response: LocalizedStringKey = "Hello! How can I help you today?"

@State private var isThinking = false

textInput 的變數被用來從文字欄位中捕捉使用者的輸入。response 的變數來顯示 API所回傳的回應。考量到 API 的回應時間,我們加入了 isThinking 的變數來監控狀態並顯示動畫效果。

至於 body 的變數,請將它替換為以下的程式碼,以建立使用者介面:

VStack(alignment: .leading) {
    
    ScrollView {
        VStack {
            Text(response)
                .font(.system(.title, design: .rounded, weight: .medium))
                .opacity(isThinking ? 0.2 : 1.0)
        }
    }
    .contentMargins(.horizontal, 15, for: .scrollContent)
    
    Spacer()
    
    HStack {
        
        TextField("Type your message here", text: $textInput)
            .textFieldStyle(.plain)
            .padding()
            .background(Color(.systemGray6))
            .clipShape(RoundedRectangle(cornerRadius: 20))
        
    }
    .padding(.horizontal)
}

這段程式碼非常直接,應該不用解釋,特別是你已有一些 SwiftUI 的開發經驗。當你修改後,就應該能在預覽中看到以下的使用者介面。

與 Google Gemini 整合

在你使用 Google Gemini APIs 前,首先需要引用 GoogleGenerativeAI 的模組:

import GoogleGenerativeAI

接下來,宣告一個 model 變數並像這樣初始化 Generative model:

let model = GenerativeModel(name: "gemini-pro", apiKey: APIKey.default)

在此,我們利用了 gemini-pro 模型,該模型專為從文字輸入中生成文字而設計。

為了將文字發送到 Google Gemini,讓我們建立一個新的函數叫做 sendMessage()

func sendMessage() {
    response = "Thinking..."
    
    withAnimation(.easeInOut(duration: 0.6).repeatForever(autoreverses: true)) {
        isThinking.toggle()
    }
    
    Task {
        do {
            let generatedResponse = try await model.generateContent(textInput)
            
            guard let text = generatedResponse.text else  {
                textInput = "Sorry, Gemini got some problems.\nPlease try again later."
                return
            }
            
            textInput = ""
            response = LocalizedStringKey(text)
            
            isThinking.toggle()
        } catch {
            response = "Something went wrong!\n\(error.localizedDescription)"
        }
    }
}

如你從上面的程式碼看到的,你只需要呼叫模型的 generateContent 方法來輸入文字並收到生成的回應。結果是以Markdown格式表達,因此我們用 LocalizedStringKey 來包裹回傳的文字。

為了呼叫 sendMessage() 函數,更新 TextField 的視圖並附上 onSubmit 的修飾詞:

TextField("Type your message here", text: $textInput)
    .textFieldStyle(.plain)
    .padding()
    .background(Color(.systemGray6))
    .clipShape(RoundedRectangle(cornerRadius: 20))
    .onSubmit {
        sendMessage()
    }

在這種情況下,當使用者完成輸入文字並按下 return 鍵時,會呼叫 sendMessage() 函數將文字提交給 Google Gemini。

就是這樣!你現在可以在模擬器中運行應用程式,或是直接在預覽中執行來測試 AI 功能。

總結

這篇教學展示了如何將 Google Gemini AI 集成到 SwiftUI 應用程式中。只需要幾行程式碼就可以讓你的應用程式擁有 Generative AI 的功能。在這個示範中,我們使用 gemini-pro 模型從純文字輸入中生成文字。

然而,Gemini AI 的能力並不僅限於基於文字的輸入。Gemini 還提供了一種名為 gemini-pro-vision 的多模態模型,允許開發者輸入文字和圖像。我們鼓勵你充分利用這個教學,透過修改提供的程式碼和進行實驗。

如果你對這篇教學有任何問題,請在下方留言讓我知道。

作者
Simon Ng
軟體工程師,AppCoda 創辦人。著有《iOS 17 App 程式設計實戰心法》、《iOS 17 App程式設計進階攻略》以及《精通SwiftUI》。曾任職於HSBC, FedEx等跨國企業,專責軟體開發、系統設計。2012年創立AppCoda技術部落格,定期發表iOS程式教學文章。現時專注發展AppCoda業務,致力於iOS程式教學、產品設計及開發。你可以到推特與我聯絡。
評論
更多來自 AppCoda 中文版
很好! 你已成功註冊。
歡迎回來! 你已成功登入。
你已成功訂閱 AppCoda 中文版 電子報。
你的連結已失效。
成功! 請檢查你的電子郵件以獲取用於登入的連結。
好! 你的付費資料已更新。
你的付費方式並未更新。