Firebase iOS Codelab Swift

1. סקירה כללית

2efe6805ef369641.png

ברוכים הבאים למעבדת הקוד של 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. בנה את אפליקציית המתנע

2f4c98d858c453fe.png

כדי לבנות את אפליקציית המתנע:

  1. בחלון מסוף, נווט אל android_studio_folder.png ספריית ios-starter/swift-starter מהורדת הקוד לדוגמה שלך
  2. הפעל pod install --repo-update
  3. פתח את הקובץ FriendlyChatSwift.xcworkspace כדי לפתוח את הפרויקט ב-Xcode.
  4. לחץ על 98205811bbed9d74.png כפתור הפעלה .

אתה אמור לראות את מסך הבית של Friendly Chat מופיע לאחר מספר שניות. ממשק המשתמש אמור להופיע. עם זאת, בשלב זה אינך יכול להיכנס, לשלוח או לקבל הודעות. האפליקציה תבטל עם חריגה עד שתשלים את השלב הבא.

4. צור פרויקט מסוף Firebase

צור פרויקט

ממסוף Firebase בחר הוסף פרויקט .

התקשר לפרויקט FriendlyChat , ולאחר מכן לחץ על צור פרויקט .

צילום מסך מ-2015-11-06 14:13:39.png

חבר את אפליקציית iOS שלך

  1. ממסך סקירת הפרויקט של הפרויקט החדש שלך, לחץ על הוסף Firebase לאפליקציית iOS שלך .
  2. הזן את מזהה החבילה, בתור " com.google.firebase.codelab.FriendlyChatSwift ".
  3. הזן את מזהה App Store בתור " 123456 ".
  4. לחץ על הרשמה אפליקציה .

הוסף את קובץ GoogleService-Info.plist לאפליקציה שלך

במסך השני לחץ על הורד את GoogleService-Info.plist כדי להוריד קובץ תצורה המכיל את כל המטא נתונים הדרושים של Firebase עבור האפליקציה שלך. העתק את הקובץ הזה ליישום שלך והוסף אותו ליעד FriendlyChatSwift .

כעת תוכל ללחוץ על ה-x בפינה הימנית העליונה של החלון הקופץ כדי לסגור אותו - דילוג על שלבים 3 ו-4 - כפי שתבצע את השלבים האלה כאן.

19d59efb213ddbdc.png

ייבוא ​​מודול 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 בשם המשתמשים שלך, תצטרך להפעיל אותה

  1. נווט אל מסוף Firebase ובחר בפרויקט שלך
  2. בחר אימות
  3. בחר בכרטיסייה שיטת כניסה
  4. העבר את מתג Google למצב מופעל (כחול)
  5. לחץ על שמור בתיבת הדו-שיח שנוצרה

אם אתה מקבל שגיאות מאוחר יותר במעבדת הקוד הזה עם ההודעה "CONFIGURATION_NOT_FOUND", חזור לשלב זה ובדוק שוב את עבודתך.

אשר את התלות של Firebase Auth

ודא שקיימות תלות של Firebase Auth בקובץ Podfile .

Podfile

pod 'Firebase/Auth'

הגדר את Info.plist שלך עבור Google Sign In.

תצטרך להוסיף סכימת URL מותאמת אישית לפרויקט XCode שלך.

  1. פתח את תצורת הפרויקט שלך: לחץ פעמיים על שם הפרויקט בתצוגת העץ השמאלית. בחר את האפליקציה שלך מהקטע 'יעדים' ולאחר מכן בחר בכרטיסייה 'מידע' והרחב את הקטע 'סוגי כתובות אתרים'.
  2. לחץ על הלחצן + והוסף סכימת URL עבור מזהה הלקוח ההפוך שלך. כדי למצוא ערך זה, פתח את קובץ התצורה של GoogleService-Info.plist וחפש את מפתח REVERSED_CLIENT_ID. העתק את הערך של המפתח הזה, והדבק אותו בתיבה סכימות URL בדף התצורה. השאר את השדות האחרים ריקים.
  3. לאחר השלמתו, התצורה שלך אמורה להיראות משהו דומה להלן (אבל עם הערכים הספציפיים ליישום שלך):

1b54d5bd2f4f1448.png

הגדר זיהוי לקוח עבור 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)")
    }
  }

בדוק קריאת הודעות כמשתמש מחובר

  1. לחץ על 98205811bbed9d74.png כפתור הפעלה .
  2. אתה אמור להישלח מיד למסך הכניסה. הקש על כפתור הכניסה של Google.
  3. לאחר מכן, אתה אמור להישלח למסך ההודעות אם הכל עבד כשורה.

6. הפעל את מסד נתונים בזמן אמת

2efe6805ef369641.png

ייבוא ​​הודעות

בפרויקט שלך במסוף Firebase בחר את הפריט מסד נתונים בסרגל הניווט השמאלי. בתפריט ההצפה של מסד הנתונים בחר ייבוא ​​JSON . דפדף אל הקובץ initial_messages.json בספריית friendlychat, בחר בו ולאחר מכן לחץ על כפתור ייבוא . זה יחליף את כל הנתונים שנמצאים כעת במסד הנתונים שלך. אתה יכול גם לערוך את מסד הנתונים ישירות, באמצעות ה-+ הירוק וה-x האדום כדי להוסיף ולהסיר פריטים.

20ccf4856b715b4c.png

לאחר הייבוא ​​מסד הנתונים שלך אמור להיראות כך:

f3e0367f1c9cd187.png

אשר את התלות במסד הנתונים של 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
  }

בדוק את סנכרון ההודעות

  1. לחץ על 98205811bbed9d74.png כפתור הפעלה .
  2. לחץ על הלחצן היכנס כדי להתחיל כדי לעבור לחלון ההודעות.
  3. הוסף הודעות חדשות ישירות במסוף Firebase על ידי לחיצה על הסמל + הירוק לצד הערך "הודעות" והוספת אובייקט כמו הבא: f9876ffc8b316b14.png
  4. אשר שהם מופיעים בממשק המשתמש של 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)
  }

בדיקת שליחת הודעות

  1. לחץ על 98205811bbed9d74.png כפתור הפעלה .
  2. לחץ על היכנס כדי לעבור לחלון ההודעות.
  3. הקלד הודעה ולחץ על שלח. ההודעה החדשה צריכה להיות גלויה בממשק המשתמש של האפליקציה ובמסוף Firebase.

8. אחסן וקבל תמונות

אשר את התלות באחסון Firebase

בבלוק התלות של ה- Podfile , אשר את כלול Firebase/Storage .

Podfile

pod 'Firebase/Storage'

הפעל את Firebase Storage בלוח המחוונים

עבור אל מסוף Firebase ואשר שאחסון מופעל עם הדומיין "gs://PROJECTID.appspot.com"

b0438b37a588bcee.png

אם אתה רואה את חלון ההפעלה במקום זאת, לחץ על "התחל" כדי להפעיל אותו עם כללי ברירת מחדל.

c290bbebff2cafa7.png

הגדר את 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])
      }
    }
  }

בדיקת שליחה וקבלה של הודעות תמונה

  1. לחץ על 98205811bbed9d74.png כפתור הפעלה .
  2. לחץ על היכנס כדי לעבור לחלון ההודעות.
  3. לחץ על סמל "הוסף תמונה" כדי לבחור תמונה. ההודעה החדשה עם התמונה צריכה להיות גלויה בממשק המשתמש של האפליקציה ובמסוף Firebase.

10. מזל טוב!

השתמשת ב-Firebase כדי לבנות בקלות אפליקציית צ'אט בזמן אמת.

מה שכיסינו

  • מסד נתונים בזמן אמת
  • כניסה פדרית
  • אִחסוּן

למד עוד