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 18 App 程式設計實戰心法》、《iOS 18 App程式設計進階攻略》以及《精通SwiftUI》。曾任職於HSBC, FedEx等跨國企業,專責軟體開發、系統設計。2012年創立AppCoda技術部落格,定期發表iOS程式教學文章。現時專注發展AppCoda業務,致力於iOS程式教學、產品設計及開發。你可以到推特與我聯絡。
評論
更多來自 AppCoda 中文版
如何在 SwiftUI App 中開發 Live Activities
SwiftUI 框架

如何在 SwiftUI App 中開發 Live Activities

Live Activities 首次於 iOS 16 推出,是 Apple 最令人興奮的更新之一,能讓 App 與使用者在即時互動上更有連結。它不再需要使用者不斷打開 App,Live Activities 可以讓資訊直接顯示在鎖定畫面和 Dynamic Island 上。
使用 Tool Calling 強化 Foundation Models 功能
AI

使用 Tool Calling 強化 Foundation Models 功能

在前幾篇教學中,我們介紹了 Foundation Models 在 iOS 26 中的運作方式,以及如何使用這個全新框架打造具備 AI 功能的應用。我們也介紹了 @Generable 巨集,它能輕鬆地將模型回應轉換為結構化的 Swift 類型。 現在,在這個 Foundation
活用 Foundation Models 的 @Generable 與 @Guide 製作測驗 App
AI

活用 Foundation Models 的 @Generable 與 @Guide 製作測驗 App

在前一篇教學中,我們介紹了 Foundation Models 框架,並示範了如何用它來進行基本的內容生成。那個過程相當簡單——你提供一個提示詞(prompt),等幾秒鐘,就能獲得自然語言的回應。在我們的範例中,我們建立了一個簡單的問答 App,讓使用者可以提問,App 則直接顯示生成的文字。 但如果回應變得更複雜——你需要把非結構化文字轉換為結構化的物件呢? 舉例來說,
很好! 你已成功註冊。
歡迎回來! 你已成功登入。
你已成功訂閱 AppCoda 中文版 電子報。
你的連結已失效。
成功! 請檢查你的電子郵件以獲取用於登入的連結。
好! 你的付費資料已更新。
你的付費方式並未更新。