1. סקירה כללית
ברוכים הבאים למעבדת הקוד של Friendly Chat. במעבדת קוד זה, תלמד כיצד להשתמש בפלטפורמת Firebase ליצירת יישומי iOS. אתה תטמיע לקוח צ'אט ותעקוב אחר הביצועים שלו באמצעות Firebase.
מה תלמד
- אפשר למשתמשים להיכנס.
- סנכרן נתונים באמצעות מסד הנתונים בזמן אמת של Firebase.
- אחסן קבצים בינאריים ב-Firebase Storage.
מה אתה צריך
- Xcode
- CocoaPods
- מכשיר בדיקה עם iOS 8.0+ או סימולטור
כיצד תשתמש במדריך זה?
איך תדרג את החוויה שלך בבניית אפליקציות ל-iOS?
2. קבל את הקוד לדוגמה
שכבו את מאגר GitHub משורת הפקודה.
$ git clone https://github.com/firebase/codelab-friendlychat-ios
3. בנה את אפליקציית המתנע
כדי לבנות את אפליקציית המתנע:
- בחלון מסוף, נווט אל ספריית
ios-starter/swift-starter
מהורדת הקוד לדוגמה שלך - הפעל
pod install --repo-update
- פתח את הקובץ FriendlyChatSwift.xcworkspace כדי לפתוח את הפרויקט ב-Xcode.
- לחץ על כפתור הפעלה .
אתה אמור לראות את מסך הבית של Friendly Chat מופיע לאחר מספר שניות. ממשק המשתמש אמור להופיע. עם זאת, בשלב זה אינך יכול להיכנס, לשלוח או לקבל הודעות. האפליקציה תבטל עם חריגה עד שתשלים את השלב הבא.
4. צור פרויקט מסוף Firebase
צור פרויקט
ממסוף Firebase בחר הוסף פרויקט .
התקשר לפרויקט FriendlyChat
, ולאחר מכן לחץ על צור פרויקט .
חבר את אפליקציית iOS שלך
- ממסך סקירת הפרויקט של הפרויקט החדש שלך, לחץ על הוסף Firebase לאפליקציית iOS שלך .
- הזן את מזהה החבילה, בתור "
com.google.firebase.codelab.FriendlyChatSwift
". - הזן את מזהה App Store בתור "
123456
". - לחץ על הרשמה אפליקציה .
הוסף את קובץ GoogleService-Info.plist לאפליקציה שלך
במסך השני לחץ על הורד את GoogleService-Info.plist כדי להוריד קובץ תצורה המכיל את כל המטא נתונים הדרושים של Firebase עבור האפליקציה שלך. העתק את הקובץ הזה ליישום שלך והוסף אותו ליעד FriendlyChatSwift .
כעת תוכל ללחוץ על ה-x בפינה הימנית העליונה של החלון הקופץ כדי לסגור אותו - דילוג על שלבים 3 ו-4 - כפי שתבצע את השלבים האלה כאן.
ייבוא מודול Firebase
התחל בכך שתוודא שמודול Firebase
מיובא.
AppDelegate.swift , FCViewController.swift
import Firebase
הגדר את Firebase ב-AppDelegate
השתמש בשיטת "הגדר" ב-FirebaseApp בתוך הפונקציה application:didFinishLaunchingWithOptions כדי להגדיר את שירותי Firebase הבסיסיים מקובץ ה-plist שלך.
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
GIDSignIn.sharedInstance().delegate = self
return true
}
5. זיהוי משתמשים
השתמש בכללים כדי להגביל למשתמשים מאומתים
כעת נוסיף כלל לדרוש אימות לפני קריאה או כתיבה של הודעות. לשם כך אנו מוסיפים את הכללים הבאים לאובייקט נתוני ההודעות שלנו. מתוך הקטע מסד נתונים של מסוף Firebase בחר מסד נתונים בזמן אמת, ולאחר מכן לחץ על הכרטיסייה כללים. לאחר מכן עדכן את הכללים כך שיראו כך:
{
"rules": {
"messages": {
".read": "auth != null",
".write": "auth != null"
}
}
}
למידע נוסף על איך זה עובד (כולל תיעוד על המשתנה "auth") עיין בתיעוד האבטחה של Firebase .
הגדר ממשקי API של אימות
לפני שהאפליקציה שלך תוכל לגשת ל-Firebase Authentication APIs בשם המשתמשים שלך, תצטרך להפעיל אותה
- נווט אל מסוף Firebase ובחר בפרויקט שלך
- בחר אימות
- בחר בכרטיסייה שיטת כניסה
- העבר את מתג Google למצב מופעל (כחול)
- לחץ על שמור בתיבת הדו-שיח שנוצרה
אם אתה מקבל שגיאות מאוחר יותר במעבדת הקוד הזה עם ההודעה "CONFIGURATION_NOT_FOUND", חזור לשלב זה ובדוק שוב את עבודתך.
אשר את התלות של Firebase Auth
ודא שקיימות תלות של Firebase Auth בקובץ Podfile
.
Podfile
pod 'Firebase/Auth'
הגדר את Info.plist שלך עבור Google Sign In.
תצטרך להוסיף סכימת URL מותאמת אישית לפרויקט XCode שלך.
- פתח את תצורת הפרויקט שלך: לחץ פעמיים על שם הפרויקט בתצוגת העץ השמאלית. בחר את האפליקציה שלך מהקטע 'יעדים' ולאחר מכן בחר בכרטיסייה 'מידע' והרחב את הקטע 'סוגי כתובות אתרים'.
- לחץ על הלחצן + והוסף סכימת URL עבור מזהה הלקוח ההפוך שלך. כדי למצוא ערך זה, פתח את קובץ התצורה של GoogleService-Info.plist וחפש את מפתח REVERSED_CLIENT_ID. העתק את הערך של המפתח הזה, והדבק אותו בתיבה סכימות URL בדף התצורה. השאר את השדות האחרים ריקים.
- לאחר השלמתו, התצורה שלך אמורה להיראות משהו דומה להלן (אבל עם הערכים הספציפיים ליישום שלך):
הגדר זיהוי לקוח עבור Google Sign In
לאחר הגדרת Firebase, נוכל להשתמש במזהה הלקוח כדי להגדיר את Google Sign In בשיטת "didFinishLaunchingWithOptions:".
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID
GIDSignIn.sharedInstance().delegate = self
return true
}
הוסף את מטפל הכניסה
לאחר שהתוצאה של הכניסה של Google הצליחה, השתמש בחשבון כדי לאמת עם Firebase.
AppDelegate.swift
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error?) {
if let error = error {
print("Error \(error)")
return
}
guard let authentication = user.authentication else { return }
let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken,
accessToken: authentication.accessToken)
Auth.auth().signIn(with: credential) { (user, error) in
if let error = error {
print("Error \(error)")
return
}
}
}
היכנס אוטומטית למשתמש. לאחר מכן הוסף מאזין ל-Firebase Auth, כדי לאפשר למשתמש להיכנס לאפליקציה, לאחר כניסה מוצלחת. והסר את המאזין ב-deinit.
SignInViewController.swift
override func viewDidLoad() {
super.viewDidLoad()
GIDSignIn.sharedInstance().uiDelegate = self
GIDSignIn.sharedInstance().signInSilently()
handle = Auth.auth().addStateDidChangeListener() { (auth, user) in
if user != nil {
MeasurementHelper.sendLoginEvent()
self.performSegue(withIdentifier: Constants.Segues.SignInToFp, sender: nil)
}
}
}
deinit {
if let handle = handle {
Auth.auth().removeStateDidChangeListener(handle)
}
}
התנתק
הוסף את שיטת היציאה
FCViewController.swift
@IBAction func signOut(_ sender: UIButton) {
let firebaseAuth = Auth.auth()
do {
try firebaseAuth.signOut()
dismiss(animated: true, completion: nil)
} catch let signOutError as NSError {
print ("Error signing out: \(signOutError.localizedDescription)")
}
}
בדוק קריאת הודעות כמשתמש מחובר
- לחץ על כפתור הפעלה .
- אתה אמור להישלח מיד למסך הכניסה. הקש על כפתור הכניסה של Google.
- לאחר מכן, אתה אמור להישלח למסך ההודעות אם הכל עבד כשורה.
6. הפעל את מסד נתונים בזמן אמת
ייבוא הודעות
בפרויקט שלך במסוף Firebase בחר את הפריט מסד נתונים בסרגל הניווט השמאלי. בתפריט ההצפה של מסד הנתונים בחר ייבוא JSON . דפדף אל הקובץ initial_messages.json
בספריית friendlychat, בחר בו ולאחר מכן לחץ על כפתור ייבוא . זה יחליף את כל הנתונים שנמצאים כעת במסד הנתונים שלך. אתה יכול גם לערוך את מסד הנתונים ישירות, באמצעות ה-+ הירוק וה-x האדום כדי להוסיף ולהסיר פריטים.
לאחר הייבוא מסד הנתונים שלך אמור להיראות כך:
אשר את התלות במסד הנתונים של Firebase
בבלוק התלות של קובץ Podfile
, אשר ש- Firebase/Database
נכלל.
Podfile
pod 'Firebase/Database'
סנכרן הודעות קיימות
הוסף קוד שמסנכרן הודעות חדשות שנוספו לממשק המשתמש של האפליקציה.
הקוד שתוסיף בסעיף זה יהיה:
- אתחל את מסד הנתונים של Firebase והוסף מאזין כדי לטפל בשינויים שנעשו במסד הנתונים.
- עדכן את
DataSnapshot
כך שהודעות חדשות יוצגו.
שנה את שיטות ה-"deinit", "configureDatabase" ו-"tableView:cellForRow indexPath:" של FCViewController שלך; החלף בקוד המוגדר להלן:
FCViewController.swift
deinit {
if let refHandle = _refHandle {
self.ref.child("messages").removeObserver(withHandle: _refHandle)
}
}
func configureDatabase() {
ref = Database.database().reference()
// Listen for new messages in the Firebase database
_refHandle = self.ref.child("messages").observe(.childAdded, with: { [weak self] (snapshot) -> Void in
guard let strongSelf = self else { return }
strongSelf.messages.append(snapshot)
strongSelf.clientTable.insertRows(at: [IndexPath(row: strongSelf.messages.count-1, section: 0)], with: .automatic)
})
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Dequeue cell
let cell = self.clientTable.dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath)
// Unpack message from Firebase DataSnapshot
let messageSnapshot = self.messages[indexPath.row]
guard let message = messageSnapshot.value as? [String: String] else { return cell }
let name = message[Constants.MessageFields.name] ?? ""
let text = message[Constants.MessageFields.text] ?? ""
cell.textLabel?.text = name + ": " + text
cell.imageView?.image = UIImage(named: "ic_account_circle")
if let photoURL = message[Constants.MessageFields.photoURL], let URL = URL(string: photoURL),
let data = try? Data(contentsOf: URL) {
cell.imageView?.image = UIImage(data: data)
}
return cell
}
בדוק את סנכרון ההודעות
- לחץ על כפתור הפעלה .
- לחץ על הלחצן היכנס כדי להתחיל כדי לעבור לחלון ההודעות.
- הוסף הודעות חדשות ישירות במסוף Firebase על ידי לחיצה על הסמל + הירוק לצד הערך "הודעות" והוספת אובייקט כמו הבא:
- אשר שהם מופיעים בממשק המשתמש של Friendly-Chat.
7. שלח הודעות
יישם שלח הודעה
דחוף ערכים למסד הנתונים. כאשר אתה משתמש בשיטת הדחיפה כדי להוסיף נתונים ל-Firebase Realtime Database, יתווסף מזהה אוטומטי. המזהים שנוצרו אוטומטית הם עוקבים, מה שמבטיח שהודעות חדשות יתווספו בסדר הנכון.
שנה את שיטת "sendMessage:" של FCViewController שלך; החלף בקוד המוגדר להלן:
FCViewController.swift
func sendMessage(withData data: [String: String]) {
var mdata = data
mdata[Constants.MessageFields.name] = Auth.auth().currentUser?.displayName
if let photoURL = Auth.auth().currentUser?.photoURL {
mdata[Constants.MessageFields.photoURL] = photoURL.absoluteString
}
// Push data to Firebase Database
self.ref.child("messages").childByAutoId().setValue(mdata)
}
בדיקת שליחת הודעות
- לחץ על כפתור הפעלה .
- לחץ על היכנס כדי לעבור לחלון ההודעות.
- הקלד הודעה ולחץ על שלח. ההודעה החדשה צריכה להיות גלויה בממשק המשתמש של האפליקציה ובמסוף Firebase.
8. אחסן וקבל תמונות
אשר את התלות באחסון Firebase
בבלוק התלות של ה- Podfile
, אשר את כלול Firebase/Storage
.
Podfile
pod 'Firebase/Storage'
הפעל את Firebase Storage בלוח המחוונים
עבור אל מסוף Firebase ואשר שאחסון מופעל עם הדומיין "gs://PROJECTID.appspot.com"
אם אתה רואה את חלון ההפעלה במקום זאת, לחץ על "התחל" כדי להפעיל אותו עם כללי ברירת מחדל.
הגדר את FirebaseStorage
FCViewController.swift
func configureStorage() {
storageRef = Storage.storage().reference()
}
קבלת תמונות בהודעות קיימות
הוסף קוד שמוריד תמונות מ-Firebase Storage.
שנה את שיטת "tableView: cellForRowAt indexPath:" של FCViewController שלך; החלף בקוד המוגדר להלן:
FCViewController.swift
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Dequeue cell
let cell = self.clientTable .dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath)
// Unpack message from Firebase DataSnapshot
let messageSnapshot: DataSnapshot! = self.messages[indexPath.row]
guard let message = messageSnapshot.value as? [String:String] else { return cell }
let name = message[Constants.MessageFields.name] ?? ""
if let imageURL = message[Constants.MessageFields.imageURL] {
if imageURL.hasPrefix("gs://") {
Storage.storage().reference(forURL: imageURL).getData(maxSize: INT64_MAX) {(data, error) in
if let error = error {
print("Error downloading: \(error)")
return
}
DispatchQueue.main.async {
cell.imageView?.image = UIImage.init(data: data!)
cell.setNeedsLayout()
}
}
} else if let URL = URL(string: imageURL), let data = try? Data(contentsOf: URL) {
cell.imageView?.image = UIImage.init(data: data)
}
cell.textLabel?.text = "sent by: \(name)"
} else {
let text = message[Constants.MessageFields.text] ?? ""
cell.textLabel?.text = name + ": " + text
cell.imageView?.image = UIImage(named: "ic_account_circle")
if let photoURL = message[Constants.MessageFields.photoURL], let URL = URL(string: photoURL),
let data = try? Data(contentsOf: URL) {
cell.imageView?.image = UIImage(data: data)
}
}
return cell
}
9. שלח הודעות תמונה
יישום אחסן ושלח תמונות
העלה תמונה מהמשתמש ולאחר מכן סנכרן את כתובת האתר לאחסון של תמונה זו עם מסד הנתונים כך שתמונה זו תישלח בתוך ההודעה.
שנה את שיטת "imagePickerController: didFinishPickingMediaWithInfo:" של FCViewController שלך; החלף בקוד המוגדר להלן:
FCViewController.swift
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : Any]) {
picker.dismiss(animated: true, completion:nil)
guard let uid = Auth.auth().currentUser?.uid else { return }
// if it's a photo from the library, not an image from the camera
if #available(iOS 8.0, *), let referenceURL = info[UIImagePickerControllerReferenceURL] as? URL {
let assets = PHAsset.fetchAssets(withALAssetURLs: [referenceURL], options: nil)
let asset = assets.firstObject
asset?.requestContentEditingInput(with: nil, completionHandler: { [weak self] (contentEditingInput, info) in
let imageFile = contentEditingInput?.fullSizeImageURL
let filePath = "\(uid)/\(Int(Date.timeIntervalSinceReferenceDate * 1000))/\((referenceURL as AnyObject).lastPathComponent!)"
guard let strongSelf = self else { return }
strongSelf.storageRef.child(filePath)
.putFile(from: imageFile!, metadata: nil) { (metadata, error) in
if let error = error {
let nsError = error as NSError
print("Error uploading: \(nsError.localizedDescription)")
return
}
strongSelf.sendMessage(withData: [Constants.MessageFields.imageURL: strongSelf.storageRef.child((metadata?.path)!).description])
}
})
} else {
guard let image = info[UIImagePickerControllerOriginalImage] as? UIImage else { return }
let imageData = UIImageJPEGRepresentation(image, 0.8)
let imagePath = "\(uid)/\(Int(Date.timeIntervalSinceReferenceDate * 1000)).jpg"
let metadata = StorageMetadata()
metadata.contentType = "image/jpeg"
self.storageRef.child(imagePath)
.putData(imageData!, metadata: metadata) { [weak self] (metadata, error) in
if let error = error {
print("Error uploading: \(error)")
return
}
guard let strongSelf = self else { return }
strongSelf.sendMessage(withData: [Constants.MessageFields.imageURL: strongSelf.storageRef.child((metadata?.path)!).description])
}
}
}
בדיקת שליחה וקבלה של הודעות תמונה
- לחץ על כפתור הפעלה .
- לחץ על היכנס כדי לעבור לחלון ההודעות.
- לחץ על סמל "הוסף תמונה" כדי לבחור תמונה. ההודעה החדשה עם התמונה צריכה להיות גלויה בממשק המשתמש של האפליקציה ובמסוף Firebase.
10. מזל טוב!
השתמשת ב-Firebase כדי לבנות בקלות אפליקציית צ'אט בזמן אמת.
מה שכיסינו
- מסד נתונים בזמן אמת
- כניסה פדרית
- אִחסוּן