1. סקירה כללית
ברוכים הבאים ל-codelab של FriendlyChat ל-iOS! ב-Codelab הזה נסביר איך ליצור אפליקציית צ'אט ל-iOS עם כל התכונות הנדרשות בזמן אמת באמצעות Firebase ותכונות מודרניות של Swift כמו SwiftUI, Swift Concurrency ו-Observation framework.
מה תלמדו
- ניהול מצב באמצעות מסגרת התצפית המודרנית (
@Observable). - אימות משתמשים באמצעות אימות ב-Firebase.
- אפשר לסנכרן הודעות בצ'אט בזמן אמת באמצעות Cloud Firestore.
- אחסון והצגת תמונות באמצעות Cloud Storage for Firebase.
- גישה לממשקי Firebase API באמצעות תכונות מודרניות של Swift Concurrency.
מה צריך
- הגרסה האחרונה של Xcode
- סימולטור iOS או מכשיר בדיקה פיזי
- חשבון Google ליצירה ולניהול של פרויקט Firebase
2. קבלת קוד לדוגמה
משכפלים את המאגר ב-GitHub משורת הפקודה:
$ git clone https://github.com/firebase/codelab-friendlychat-ios
מאגר codelab-friendlychat-ios מכיל כמה פרויקטים לדוגמה:
-
ios-starter/swift-starter– פרויקט Xcode התחלתי שמכיל את השלד של פריסת SwiftUI ותגובותTODOשבהן מטמיעים תכונות של האפליקציה באמצעות Firebase. -
ios/swift– פרויקט Xcode שהושלם עם אפליקציית הדוגמה המוגמרת.
3. יצירת אפליקציה לתחילת הדרך
כדי להכיר את ממשק המשתמש, בונים ומריצים את אפליקציית המתחילים:
- ב-Finder או בטרמינל, עוברים לספרייה
ios-starter/swift-starter. - לוחצים לחיצה כפולה על
FriendlyChatSwift.xcodeprojכדי לפתוח את הפרויקט ב-Xcode. - שימו לב ש-Xcode מטפל אוטומטית ביחסי התלות של Swift Package Manager ברקע (הורדה של
firebase-ios-sdkגרסה 12 ומעלה מ-GitHub). - בוחרים סימולטור iOS (לדוגמה, iPhone 17 Pro) ולוחצים על הלחצן Run (הפעלה) (cmd+R).
אחרי כמה שניות, יופיע מסך הכניסה של FriendlyChat. בשלב הזה, לחצני הכניסה ופידי ההודעות הם placeholders. בשלבים הבאים נסביר איך לקשר את Firebase לאפליקציה.
4. הגדרת פרויקט Firebase
יצירת פרויקט חדש ב-Firebase
- נכנסים למסוף Firebase באמצעות חשבון Google.
- לוחצים על הלחצן כדי ליצור פרויקט חדש, ואז מזינים שם לפרויקט (לדוגמה,
FriendlyChat).
- לוחצים על המשך.
- אם מוצגת בקשה לעשות זאת, קוראים ומאשרים את התנאים של Firebase, ואז לוחצים על המשך.
- (אופציונלי) מפעילים את העזרה מבוססת-AI במסוף Firebase (שנקראת 'Gemini ב-Firebase').
- ב-codelab הזה לא צריך להשתמש ב-Google Analytics, ולכן משביתים את האפשרות של Google Analytics.
- לוחצים על יצירת פרויקט, מחכים שהפרויקט יוקצה ולוחצים על המשך.
שדרוג תוכנית התמחור של Firebase
כדי להשתמש ב-Cloud Storage for Firebase, הפרויקט ב-Firebase צריך להיות בתוכנית התמחור 'תשלום לפי שימוש' (Blaze), כלומר הוא צריך להיות מקושר לחשבון לחיוב ב-Cloud.
- בחשבון לחיוב ב-Cloud צריך להגדיר אמצעי תשלום, כמו כרטיס אשראי.
- אם אתם חדשים ב-Firebase וב-Google Cloud, כדאי לבדוק אם אתם עומדים בדרישות לקבלת קרדיט בשווי 300$ותקופת ניסיון בחינם בחשבון לחיוב ב-Cloud.
- אם אתם משתתפים באירוע שכולל את ה-codelab הזה, כדאי לשאול את מארגן האירוע אם יש קרדיטים ל-Cloud.
כדי לשדרג את הפרויקט לתוכנית Blaze, פועלים לפי השלבים הבאים:
- במסוף Firebase, בוחרים באפשרות שדרוג התוכנית.
- בוחרים בתוכנית Blaze. פועלים לפי ההוראות שמופיעות במסך כדי לקשר חשבון לחיוב ב-Cloud לפרויקט.
אם הייתם צריכים ליצור חשבון לחיוב ב-Cloud כחלק מהשדרוג, יכול להיות שתצטרכו לחזור לתהליך השדרוג במסוף Firebase כדי להשלים את השדרוג.
קישור אפליקציה ל-iOS
- במסך Project Overview (סקירת הפרויקט), לוחצים על הסמל iOS כדי להפעיל את תהליך העבודה להגדרת האפליקציה.
- מזינים את מזהה החבילה:
com.google.firebase.codelab.FriendlyChatSwift - לוחצים על Register app (רישום האפליקציה).
הוספה של GoogleService-Info.plist לפרויקט Xcode
- לוחצים על Download GoogleService-Info.plist כדי לשמור את קובץ ההגדרות.
- ב-Xcode, גוררים את הקובץ
GoogleService-Info.plistשהורד אל הקבוצה הראשיתFriendlyChatSwiftב-Project Navigator. - כשמוצגת בקשה, מוודאים שהתיבה העתקת פריטים אם צריך מסומנת ושנבחר יעד
FriendlyChatSwift, ואז לוחצים על סיום.
הגדרת Firebase ב-FriendlyChatSwiftApp.swift
לבסוף, מאתחלים את Firebase עם הגדרות הפרויקט כשמפעילים את אפליקציית SwiftUI. פותחים את FriendlyChatSwiftApp.swift ומחליפים את הפלייסהולדרים TODO ב-import FirebaseCore וב-FirebaseApp.configure():
import SwiftUI
import FirebaseCore
@main
struct FriendlyChatSwiftApp: App {
init() {
FirebaseApp.configure()
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
5. אימות משתמשים
הגדרת אימות במסוף Firebase
לפני שאפשר לאמת משתמשים, צריך קודם להפעיל את ספק האימות שבחרתם במסוף Firebase. במדריך הזה נעשה שימוש באימות באמצעות אימייל וסיסמה:
- במסוף Firebase, עוברים אל Security (אבטחה) > Authentication (אימות), ואז לוחצים על Get started (תחילת העבודה).
- בוחרים בכרטיסייה שיטת הכניסה.
- לוחצים על אימייל/סיסמה, לוחצים על המתג הפעלה ואז על שמירה.
הגנה על Cloud Firestore באמצעות כללי אימות
לאחר מכן, דורשים מהמשתמשים לעבור אימות לפני שהם קוראים או כותבים הודעות:
- במסוף Firebase, עוברים אל Databases & Storage (מסדי נתונים ואחסון) > Firestore Database (מסד נתונים של Firestore), ואז לוחצים על Create database (יצירת מסד נתונים).
- בוחרים מיקום ולוחצים על הבא.
- בוחרים באפשרות התחלה במצב בדיקה ולוחצים על יצירה.
- לוחצים על הכרטיסייה כללים ומעדכנים את כללי האבטחה כך:
הכללים האלה מאפשרים לכל משתמש מאומת לקרוא או לכתוב הודעות במסד הנתונים, וזה מתאים למטרות לימוד. מידע נוסף על כללי אבטחה זמין במסמכי התיעוד בנושא כללי אבטחה.rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /messages/{messageId} { allow read, write: if request.auth != null; } } } - לוחצים על פרסום.
הצגת מצב האימות ב-UserViewModel.swift
ב-SwiftUI, מעקב תגובתי אחרי מצב האימות ב-Firebase מבטיח שהממשק יעבור בצורה חלקה בין מסך הכניסה לממשק הצ'אט.
פותחים את ViewModels/UserViewModel.swift ומחליפים את TODO ב-init() כדי לראות את השינויים במצב ההרשאה באמצעות authStateChanges AsyncSequence:
init() {
authTask = Task {
for await user in Auth.auth().authStateChanges {
self.user = user
}
}
}
הטמעה של כניסה, הרשמה ויציאה באמצעות Swift Concurrency
ב-UserViewModel.swift, מחליפים את שאר ההערות TODO בשיטות אימות מודרניות async/await:
func signIn(email: String, password: String) async {
errorMessage = nil
if email.isEmpty || password.isEmpty {
showError("Please enter both email and password.")
return
}
do {
try await Auth.auth().signIn(withEmail: email, password: password)
} catch {
showError(error.localizedDescription)
}
}
func signUp(email: String, password: String, displayName: String) async {
errorMessage = nil
if email.isEmpty || password.isEmpty {
showError("Please enter both email and password.")
return
}
do {
let result =
try await Auth.auth().createUser(withEmail: email, password: password)
let changeRequest = result.user.