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 中文版
iOS 18 新API:使用 Navigation Transition 創建 Hero 動畫式過場
SwiftUI 框架

iOS 18 新API:使用 Navigation Transition 創建 Hero 動畫式過場

Apple 的工程師可能早已認識到,許多 iOS 開發者都希望能夠重現 App Store 應用程式中的優雅 Hero 動畫。由於從頭實現這種動畫通常需要耗費大量時間與精力,Apple 在 iOS 18 SDK 中納入了這項功能。 透過這次更新,你現在只需少量的程式碼就能在自己的應用程式中實現類似的動畫過渡效果。這項重大改進讓開發者能夠創造出更具視覺吸引力且流暢的過渡效果,
如何使用 Vision APIs 從圖像中辨識文字
AI

如何使用 Vision APIs 從圖像中辨識文字

Vision 框架長期以來一直包含文字識別功能。我們已經有詳細的教程,向你展示如何使用 Vision 框架掃描圖像並執行文字識別。之前,我們使用了 VNImageRequestHandler 和 VNRecognizeTextRequest 來從圖像中提取文字。 多年來,Vision 框架已經顯著演變。在 iOS 18 中,Vision
iOS 18更新:SwiftUI 新功能介紹
SwiftUI 框架

iOS 18更新:SwiftUI 新功能介紹

SwiftUI的技術不斷演進,每次更新都讓 iOS 應用程式開發變得更加便捷。隨著 iOS 18 Beta 的推出,SwiftUI 引入了多個令人興奮的新功能,使開發者僅需幾行程式碼即可實現出色的效果。 本教學文章旨在探索這個版本中的幾項主要改進,幫助你了解如何運用這些新功能。 浮動標籤列 (Floating Tab Bar)SwiftUI中的標籤視圖(Tab
很好! 你已成功註冊。
歡迎回來! 你已成功登入。
你已成功訂閱 AppCoda 中文版 電子報。
你的連結已失效。
成功! 請檢查你的電子郵件以獲取用於登入的連結。
好! 你的付費資料已更新。
你的付費方式並未更新。