摘要
本文將深入探討如何將 SwiftUI 與 Firebase 認證整合,以實現自訂 Google 登入,提升使用者體驗及安全性。 歸納要點:
- 無縫使用者體驗:SwiftUI 的介面設計結合 Firebase 認證,讓開發者輕鬆打造直觀的登入流程。
- 強大的安全機制:Firebase 提供密碼加密和即時身分驗證,保護應用程式免受未經授權存取的威脅。
- 自訂 Google 登入:開發者可以根據需求調整 Google 登入按鈕,提高使用者介面的一致性與品牌形象。
透過 SwiftUI 提升使用者體驗
Firebase Authentication 是一個強大的工具,讓您能夠實時儲存和同步資料。SwiftUI 則是一個現代化的 UI 框架,使得建立美觀且互動性強的使用者介面變得簡單。在本文中,我們將向您展示如何結合這兩項技術,以使用 Google 登入,若要使用 Apple 登入請點選此處。如果您想了解 Firebase 實時資料庫,請點選此處;如果您想學習如何使用 Firebase 建立網站,請點選此處。我們將從建立一個簡單的 SwiftUI 專案並新增 Firebase SDK 開始。接著,我們將建立一個模型來表示我們的自定義文字。我們會建立一個顯示 Google 登入按鈕的檢視。在本文結束時,您將知道如何利用 Firebase Authentication 和 SwiftUI 顯示 Google 登入介面。這些知識對於為任何應用程式建立身份驗證檢視非常有用,同時也簡化了檢視設計。**1. 使用 SwiftUI 建立更直覺的 UI**:Firebase 驗證與 SwiftUI 的結合,不僅讓開發者可以使用直覺的 API 編寫 UI 程式碼,也讓他們能夠更加專注於提升使用者體驗的設計,從而簡化開發流程並增進介面的易用性和美觀性。
Firebase:無痛開發應用程式的後端即服務 (BaaS)
什麼是 Firebase?Firebase 是一個後端即服務(Backend-as-a-Service, BaaS)平台,為移動應用程式開發提供託管的後端服務。它擁有廣泛的功能,包括實時資料庫、雲端儲存、身份驗證、崩潰報告、機器學習、遠端配置以及靜態檔案的託管等。Firebase 使得開發和擴充套件應用變得簡單,而無需擔心基礎設施問題。您可以在這裡了解更多關於 Firebase 的資訊。建立 Firebase 帳戶是一個簡單的過程。只需前往 Firebase 網站並點選「登入」按鈕。您可以使用電子郵件地址登入,也可以透過點選「註冊」按鈕建立新帳戶,然後按照相應的註冊步驟進行操作。
完成上述步驟後,您可以點選「前往控制檯」,這將帶您到以下頁面。在此之後,您就能夠開始利用 Firebase 提供的各項功能來開發您的應用程式了。
值得一提的是,**Firebase 雲端訊息 (Cloud Messaging)** 讓開發人員能夠安全地向裝置傳送訊息,而無需管理裝置憑證或協調多個平台。**Firebase ML Kit** 則提供了一系列機器學習模型,使得將機器學習功能整合至應用中變得輕而易舉,助力開發者打造更智慧、更具互動性的應用程式。
我們在研究許多文章後,彙整重點如下
網路文章觀點與我們總結
- 保持良好的作息能提升生活品質和工作效率。
- 運動有助於減壓,增強身體健康。
- 飲食均衡對於精神狀態和體能表現至關重要。
- 學習新技能可以激發大腦活力,提高自我滿足感。
- 社交活動有助於建立人際關係,增加幸福感。
- 定期自我反思有助於了解自己的需求與目標。
在日常生活中,我們經常忽視一些小細節,但這些卻是影響我們整體幸福感的重要因素。良好的作息、適度的運動以及均衡的飲食,不僅能提高我們的身心狀態,還能讓我們在繁忙的生活中找到平衡。此外,持續學習和參加社交活動也能帶來意想不到的快樂與成就感。透過定期反思,我們更能把握自己的方向,朝著理想生活邁進。
觀點延伸比較:主題 | 最新趨勢 | 權威觀點 | 實用建議 |
---|---|---|---|
良好作息 | 越來越多人關注睡眠質量,使用科技產品追蹤睡眠數據 | 根據美國睡眠協會,成年人每晚應至少獲得7小時的高質量睡眠以提高工作效率和生活品質 | 建立固定的作息時間,避免臨睡前使用電子產品。 |
運動 | 居家健身與線上課程受歡迎,特別是瑜伽和高強度間歇訓練(HIIT) | 專業健身教練指出,每週至少150分鐘中等強度有氧運動能顯著減輕壓力並增強免疫系統 | 設定每周運動計劃,結合不同類型的運動以保持新鮮感。 |
飲食均衡 | 植物性飲食和超級食品逐漸成為健康飲食的新潮流,如藜麥、奇亞籽等被廣泛推崇 | 營養學家建議攝取豐富色彩的蔬菜水果,以確保獲得必要的維生素及礦物質,提高精神狀態和體能表現 | 準備一週餐計劃,選擇當季新鮮食材並嘗試製作健康美味的餐點。 |
學習新技能 | 線上學習平台如Coursera、Udemy持續興起,使得技能提升變得更加便利 | 心理學研究顯示,不斷挑戰自己可以促進大腦神經可塑性,有助於長期記憶與創造力發展 | 定期參加工作坊或社區課程,在互動中激發靈感與創意。 |
社交活動 | 虛擬社交工具如Zoom和Discord讓人們即使遠距離也能保持聯繫 | 人際關係專家強調,良好的社交支持系統對心理健康至關重要,有助於減少焦慮與抑鬱症狀 | 制定每月社交日曆,包括聚會、志願者活動或家庭聚餐等,加強人際連結。 |
建立專案頁面要建立一個新的應用程式,請點選「建立專案」按鈕。第一步是為您的專案命名並同意 Firebase 的使用條款。
第二步是選擇是否希望將 Google Analytics 連線到您的應用程式。
步驟二:Google Analytics 第三步是配置你的 Google Analytics。
配置 Google Analytics 等待 Firebase 建立您的專案時請稍候。
按下繼續這是專案概覽頁面。恭喜您成功設定 Firebase!本文將重點介紹 Firebase 最強大的功能之一:實時資料庫(Realtime Database)。
專案概述 要將 Firebase 加入 iOS 應用程式,您可以按下 iOS 按鈕,這將帶您進入此頁面。請依照所有步驟操作,然後點選繼續到控制檯。
將 Firebase 新增到您的 Apple 應用程式中。在您完成所有五個步驟後,我們可以開始建立資料庫。前往所有產品頁面,然後點選即時資料庫(Realtime Database)選項。
點選認證後,您將進入這個頁面。然後,按下「開始使用」按鈕。
一旦您點選了「開始」按鈕,您將會被帶到這裡。
現在點選 Google 按鈕。
翻轉啟用開關,並新增電子郵件。
點選儲存按鈕以啟用 Google 作為選項。
在使用 Xcode 時,您需要新增這個套件,這可以透過選擇檔案 -> 新增套件來完成,然後輸入以下連結,點選確切版本: https://github.com/firebase/firebase-ios-sdk。 接下來,新增 Google Service Info plist。從 Firebase 設定中下載它,在您新增應用程式之後。然後將反向客戶端 ID 放置在此處的資訊和 URL 連結下方。
第一步是對你的應用程式進行 Firebase 的配置。這個配置是在 App 結構中完成的,Firebase 在此被初始化:
import Firebase import FirebaseAuth import FirebaseCore import Foundation import GoogleSignIn import SwiftUI @main struct Firebase_Test_CodeApp: App { init() { FirebaseApp.configure() } var body: some Scene { WindowGroup { ContentView().onOpenURL { url in GIDSignIn.sharedInstance.handle(url) } } } }
FirebaseApp.configure(): 在應用程式啟動時初始化 Firebase。onOpenURL: 處理應用程式開啟的 URL,用於管理 Google 登入過程。Authentication 結構負責處理 Google 登入過程並管理身份驗證狀態。
struct Authentication { func googleOauth() async throws { guard let clientID = FirebaseApp.app()?.options.clientID else { fatalError("No Firebase clientID found") } let config = GIDConfiguration(clientID: clientID) GIDSignIn.sharedInstance.configuration = config let scene = await UIApplication.shared.connectedScenes.first as? UIWindowScene guard let rootViewController = await scene?.windows.first?.rootViewController else { fatalError("There is no root view controller!") } let result = try await GIDSignIn.sharedInstance.signIn(withPresenting: rootViewController) let user = result.user guard let idToken = user.idToken?.tokenString else { throw "Unexpected error occurred, please retry" } let credential = GoogleAuthProvider.credential(withIDToken: idToken, accessToken: user.accessToken.tokenString) try await Auth.auth().signIn(with: credential) } func logout() async throws { GIDSignIn.sharedInstance.signOut() try Auth.auth().signOut() } }
googleOauth: 處理 Google OAuth 流程。配置使用來自 Firebase 的客戶端 ID 進行 Google 登入。檢索根檢視控制器以呈現登入介面。使用 Google 登入使用者並獲取 ID 令牌。利用 ID 令牌與 Firebase 認證。logout: 從 Google 和 Firebase 同時登出使用者。一個擴充套件,使 String 符合 Error,簡化錯誤處理。
extension String: Error {}
應用程式的主要檢視管理身份驗證狀態,並根據使用者是否已登入來顯示登入畫面或主畫面。
struct ContentView: View { @State private var userLoggedIn = (Auth.auth().currentUser != nil) var body: some View { VStack { if userLoggedIn { Home() } else { Login() } }.onAppear { Auth.auth().addStateDidChangeListener { auth, user in userLoggedIn = (user != nil) } } } }
@State private var userLoggedIn: 一個狀態變數,用來追蹤使用者是否已登入。Auth.auth().addStateDidChangeListener: 一個監聽器,用於在認證狀態改變時更新登入狀態。登入檢視顯示 Google 登入按鈕並處理登入過程:
struct Login: View { @State private var err: String = "" var body: some View { Text("Login") Button { Task { do { try await Authentication().googleOauth() } catch let e { err = e.localizedDescription } } } label: { HStack { Image(systemName: "person.badge.key.fill") Text("Sign in with Google") }.padding(8) }.buttonStyle(.borderedProminent) Text(err).foregroundColor(.red).font(.caption) } }
@State private var err: 一個狀態變數,用於儲存和顯示錯誤訊息。Button:啟動使用 Authentication 結構的 Google 登入流程。Home 檢視為已登入的使用者顯示問候語及登出按鈕。
struct Home: View { @State private var err: String = "" var body: some View { HStack { Image(systemName: "hand.wave.fill") Text("Hello " + (Auth.auth().currentUser!.displayName ?? "Username not found")) } Button { Task { do { try await Authentication().logout() } catch let e { err = e.localizedDescription } } } label: { Text("Log Out").padding(8) }.buttonStyle(.borderedProminent) Text(err).foregroundColor(.red).font(.caption) } }
如果可用,顯示使用者的顯示名稱;若無則顯示預設訊息。按鈕:使用 Authentication 結構登出使用者。登入和主頁檢視均包含預覽,以幫助在 Xcode 的畫布中進行視覺化:這完成了在 SwiftUI 應用程式中整合 Google 登入和 Firebase 認證的過程。按照這些步驟,您可以無縫管理使用者認證,為您的應用程式提供流暢的使用者體驗。完整程式碼如下。
import Firebase import FirebaseAuth import FirebaseCore import Foundation import GoogleSignIn import SwiftUI @main struct Firebase_Test_CodeApp: App { init() { FirebaseApp.configure() } var body: some Scene { WindowGroup { ContentView().onOpenURL { url in GIDSignIn.sharedInstance.handle(url) } } } } struct Authentication { func googleOauth() async throws { // google sign in guard let clientID = FirebaseApp.app()?.options.clientID else { fatalError("no firbase clientID found") } // Create Google Sign In configuration object. let config = GIDConfiguration(clientID: clientID) GIDSignIn.sharedInstance.configuration = config //get rootView let scene = await UIApplication.shared.connectedScenes.first as? UIWindowScene guard let rootViewController = await scene?.windows.first?.rootViewController else { fatalError("There is no root view controller!") } //google sign in authentication response let result = try await GIDSignIn.sharedInstance.signIn( withPresenting: rootViewController ) let user = result.user guard let idToken = user.idToken?.tokenString else { throw "Unexpected error occurred, please retry" } //Firebase auth let credential = GoogleAuthProvider.credential( withIDToken: idToken, accessToken: user.accessToken.tokenString ) try await Auth.auth().signIn(with: credential) } func logout() async throws { GIDSignIn.sharedInstance.signOut() try Auth.auth().signOut() } } extension String: Error {} struct ContentView: View { @State private var userLoggedIn = (Auth.auth().currentUser != nil) var body: some View { VStack { if userLoggedIn { Home() } else { Login() } }.onAppear { Auth.auth().addStateDidChangeListener { auth, user in if user != nil { userLoggedIn = true } else { userLoggedIn = false } } } } } struct Login: View { @State private var err: String = "" var body: some View { Text("Login") Button { Task { do { try await Authentication().googleOauth() } catch let e { err = e.localizedDescription } } } label: { HStack { Image(systemName: "person.badge.key.fill") Text("Sign in with Google") }.padding(8) }.buttonStyle(.borderedProminent) Text(err).foregroundColor(.red).font(.caption) } } #Preview { Login() } struct Home: View { @State private var err: String = "" var body: some View { HStack { Image(systemName: "hand.wave.fill") Text( "Hello " + (Auth.auth().currentUser!.displayName ?? "Username not found") ) } Button { Task { do { try await Authentication().logout() } catch let e { err = e.localizedDescription } } } label: { Text("Log Out").padding(8) }.buttonStyle(.borderedProminent) Text(err).foregroundColor(.red).font(.caption) } } #Preview { Home() }
如果你讀到這裡,請鼓掌。
參考來源
相關討論