Firebase iOS Codelab Swift

1. نظرة عامة

2efe6805ef369641.png

مرحبًا بك في مختبر كود الدردشة الودية. في مختبر الرموز هذا ، ستتعلم كيفية استخدام نظام Firebase الأساسي لإنشاء تطبيقات iOS. ستقوم بتنفيذ برنامج دردشة ومراقبة أدائه باستخدام Firebase.

مختبر الرموز هذا متاح أيضًا في Objective-C.

ماذا ستتعلم

  • السماح للمستخدمين بتسجيل الدخول.
  • مزامنة البيانات باستخدام قاعدة بيانات Firebase Realtime.
  • تخزين الملفات الثنائية في 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 زر التشغيل .

يجب أن تشاهد الشاشة الرئيسية للمحادثة الودية تظهر بعد بضع ثوان. يجب أن تظهر واجهة المستخدم. ومع ذلك ، في هذه المرحلة ، لا يمكنك تسجيل الدخول أو إرسال أو استقبال الرسائل. سيُجهض التطبيق باستثناء استثناء حتى تكمل الخطوة التالية.

4. إنشاء مشروع وحدة تحكم Firebase

أنشئ مشروعًا

من وحدة تحكم Firebase حدد "إضافة مشروع" .

اتصل بالمشروع FriendlyChat ، ثم انقر فوق إنشاء مشروع .

لقطة شاشة من 2015-11-06 14:13: 39.png

قم بتوصيل تطبيق iOS الخاص بك

  1. من شاشة نظرة عامة على المشروع لمشروعك الجديد ، انقر على إضافة Firebase إلى تطبيق iOS الخاص بك .
  2. أدخل معرف الحزمة ، مثل " com.google.firebase.codelab.FriendlyChatSwift ".
  3. أدخل معرف متجر التطبيقات كـ " 123456 ".
  4. انقر فوق تسجيل التطبيق .

أضف ملف GoogleService-Info.plist إلى تطبيقك

في الشاشة الثانية ، انقر فوق Download GoogleService-Info.plist لتنزيل ملف التكوين الذي يحتوي على جميع بيانات Firebase الوصفية الضرورية لتطبيقك. انسخ هذا الملف إلى تطبيقك وأضفه إلى الهدف FriendlyChatSwift .

يمكنك الآن النقر فوق "x" في الزاوية اليمنى العليا من النافذة المنبثقة لإغلاقها - تخطي الخطوتين 3 و 4 - حيث ستنفذ هاتين الخطوتين هنا.

19d59efb213ddbdc.png

استيراد وحدة Firebase

ابدأ بالتأكد من استيراد وحدة Firebase .

AppDelegate.swift ، FCViewController.swift

import Firebase

هيئ Firebase في AppDelegate

استخدم طريقة "التكوين" في FirebaseApp داخل التطبيق: دالة didFinishLaunchingWithOptions لتكوين خدمات Firebase الأساسية من ملف .plist الخاص بك.

AppDelegate.swift

  func application(_ application: UIApplication, didFinishLaunchingWithOptions
      launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
  FirebaseApp.configure()
  GIDSignIn.sharedInstance().delegate = self
  return true
}

5. تحديد المستخدمين

استخدم القواعد لتقييد المستخدمين المصادق عليهم

سنضيف الآن قاعدة لطلب المصادقة قبل قراءة أو كتابة أي رسائل. للقيام بذلك نضيف القواعد التالية إلى كائن بيانات رسائلنا. من داخل قسم قاعدة البيانات في وحدة تحكم Firebase ، حدد Realtime Database ، ثم انقر فوق علامة التبويب "القواعد". ثم قم بتحديث القواعد بحيث تبدو كما يلي:

{
  "rules": {
    "messages": {
      ".read": "auth != null",
      ".write": "auth != null"
    }
  }
}

لمزيد من المعلومات حول كيفية عمل ذلك (بما في ذلك الوثائق الخاصة بمتغير "auth") ، راجع وثائق أمان Firebase.

تكوين مصادقة واجهات برمجة التطبيقات

قبل أن يتمكن تطبيقك من الوصول إلى واجهات برمجة تطبيقات مصادقة Firebase نيابة عن المستخدمين ، سيتعين عليك تمكينها

  1. انتقل إلى وحدة تحكم Firebase وحدد مشروعك
  2. حدد المصادقة
  3. حدد علامة التبويب طريقة تسجيل الدخول
  4. بدّل مفتاح Google إلى تمكين (أزرق)
  5. اضغط على حفظ في مربع الحوار الناتج

إذا ظهرت لك أخطاء لاحقًا في مختبر الشفرات هذا بالرسالة "CONFIGURATION_NOT_FOUND" ، فارجع إلى هذه الخطوة وتحقق مرة أخرى من عملك.

قم بتأكيد تبعية Firebase Auth

تأكد من وجود تبعيات Firebase Auth في ملف Podfile .

بودفيلي

pod 'Firebase/Auth'

قم بإعداد Info.plist الخاص بك لتسجيل الدخول إلى Google.

ستحتاج إلى إضافة مخطط URL مخصص إلى مشروع XCode الخاص بك.

  1. افتح تكوين المشروع الخاص بك: انقر نقرًا مزدوجًا فوق اسم المشروع في عرض الشجرة الأيسر. حدد التطبيق الخاص بك من قسم الأهداف ، ثم حدد علامة التبويب المعلومات ، وقم بتوسيع قسم أنواع عناوين URL.
  2. انقر فوق الزر + ، وأضف مخطط URL لمعرف العميل المعكوس. للعثور على هذه القيمة ، افتح ملف تكوين GoogleService-Info.plist ، وابحث عن مفتاح REVERSED_CLIENT_ID. انسخ قيمة هذا المفتاح ، والصقها في مربع أنظمة URL في صفحة التكوين. اترك الحقول الأخرى فارغة.
  3. عند الانتهاء ، يجب أن يبدو التكوين الخاص بك مشابهًا لما يلي (ولكن مع القيم الخاصة بالتطبيق):

1b54d5bd2f4f1448.png

قم بتعيين معرف العميل لتسجيل الدخول إلى Google

بعد تهيئة Firebase ، يمكننا استخدام معرّف العميل لإعداد تسجيل الدخول إلى Google داخل طريقة "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 Sign-In.
  3. يجب أن يتم إرسالك بعد ذلك إلى شاشة المراسلة إذا كان كل شيء يعمل بشكل جيد.

6. تفعيل Realtime Database

2efe6805ef369641.png

استيراد الرسائل

في مشروعك في وحدة تحكم Firebase ، حدد عنصر قاعدة البيانات على شريط التنقل الأيسر. في القائمة الكاملة لقاعدة البيانات ، حدد استيراد JSON . تصفح إلى ملف initial_messages.json في دليل Friendlychat ، وحدده ثم انقر على زر استيراد . سيؤدي هذا إلى استبدال أي بيانات موجودة حاليًا في قاعدة البيانات الخاصة بك. يمكنك أيضًا تحرير قاعدة البيانات مباشرةً ، باستخدام الأخضر + والأحمر x لإضافة العناصر وإزالتها.

20ccf4856b715b4c.png

بعد استيراد قاعدة البيانات الخاصة بك يجب أن تبدو كما يلي:

f3e0367f1c9cd187.png

قم بتأكيد تبعية قاعدة بيانات Firebase

في كتلة التبعيات لملف Podfile ، تأكد من تضمين Firebase/Database .

بودفيلي

pod 'Firebase/Database'

مزامنة الرسائل الموجودة

أضف رمزًا يزامن الرسائل المضافة حديثًا إلى واجهة مستخدم التطبيق.

الرمز الذي تضيفه في هذا القسم سوف:

  • قم بتهيئة قاعدة بيانات Firebase وإضافة مستمع للتعامل مع التغييرات التي تم إجراؤها على قاعدة البيانات.
  • قم بتحديث DataSnapshot بحيث تظهر الرسائل الجديدة.

تعديل "deinit" و "configurationDatabase" و "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. تأكد من ظهورهم في واجهة مستخدم الدردشة الودية.

7. إرسال الرسائل

تنفيذ إرسال رسالة

دفع القيم إلى قاعدة البيانات. عند استخدام طريقة الدفع لإضافة بيانات إلى قاعدة بيانات Firebase Realtime ، ستتم إضافة معرف تلقائي. هذه المعرفات التي يتم إنشاؤها تلقائيًا هي متسلسلة ، مما يضمن إضافة الرسائل الجديدة بالترتيب الصحيح.

تعديل طريقة "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 .

بودفيلي

pod 'Firebase/Storage'

قم بتنشيط تخزين Firebase في لوحة القيادة

انتقل إلى وحدة تحكم 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. إرسال رسائل الصور

تنفيذ تخزين وإرسال الصور

قم بتحميل صورة من المستخدم ، ثم قم بمزامنة عنوان URL لتخزين هذه الصورة مع قاعدة البيانات حتى يتم إرسال هذه الصورة داخل الرسالة.

تعديل "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 لإنشاء تطبيق دردشة في الوقت الفعلي بسهولة.

ما غطينا

  • قاعدة بيانات الوقت الفعلي
  • تسجيل الدخول الموحد
  • تخزين

يتعلم أكثر